2008-09-26 16 views
35

Ich suche nach einem Stück Code, der mir den Offset eines Feldes innerhalb einer Struktur sagen kann, ohne eine Instanz der Struktur zuzuordnen.C/C++ Struktur Offset

IE:

struct mstct { 
    int myfield; 
    int myfield2; 
}; 

I schreiben konnte:

mstct thing; 
printf("offset %lu\n", (unsigned long)(&thing.myfield2 - &thing)); 

Und "Offset 4" erhalten für die Ausgabe. Wie kann ich es ohne diese "mstct thing" -Deklaration machen?

Ich weiß, dass & <struct> nicht immer auf das erste Byte des ersten Feldes der Struktur zeigen, ich kann das später erklären.

Antwort

69

Wie wäre es mit dem Standardoffsetof() Makro (in stddef.h)?

Edit: für Menschen, die nicht die offsetof() Makro verfügbar aus irgendeinem Grund haben könnte, können Sie den Effekt mit so etwas wie erhalten:

#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field)) 
+1

Nicht ganz was ich wollte, weil ich nicht stdefdef.h habe, aber es beantwortet meine Frage mit: #define offsetof (TYPE, MITGLIED) ((size_t) & ((TYPE *) 0) -> MITGLIED) – davenpcj

+3

Wow - nein stddef.h? Könnte ich nur aus Neugier fragen, was du benutzt? –

+0

Es ist in der C99-Standard, also würde ich vorschlagen, einen neuen Compiler zu bekommen. – wnoise

8

Rechts, verwenden Sie die offsetof Makro, die (zumindest mit GNU CC) ist sowohl mit C und C++ Code verfügbar:

offsetof(struct mstct, myfield2) 
+0

offsetof() ist in Standard C/C++ seit dem ersten ANSI C89 Standard gewesen. Jeder Compiler sollte es haben, es sei denn, Sie verwenden etwas ernsthaft alt. Selbst dann könnte es zusammen mit hässlichen Casting & Pointer Arithmetik zusammengeschustert werden. –

+0

Einverstanden - Ich würde höchstwahrscheinlich einen Dummy bereitstellen, um diese Makros bereitzustellen. Plauger bietet "The Standard C Library" und es ist eine einfache Header zu bieten - solange es nicht tragbar sein muss. –

+0

AFAIK, Offsetof() ist nicht Hing * aber * hässlich Casting & Zeigerarithmetik ... so etwas wie: #define offsetof (Typ, Feld) ((char *) & (((*) 0) -> Feld) - (char *) 0) –

3

printf ("Offset:% d \ n", & ((mstct *) 0) -> myfield2);

+1

Abgesehen davon, dass 'offsetof' das besser lesbar macht, kann man' ptrdiff_t' nicht generell mit '% d' drucken - auf LP64-Systemen ist es zu groß. –