Sie verwenden ein Null-Bitfeld als Hacky-Methode, um Ihren Compiler dazu zu bringen, eine Struktur anzuordnen, die externen Anforderungen entspricht, sei es die Layout-Vorstellung eines anderen Compilers oder einer anderen Architektur (plattformübergreifende Datenstrukturen wie in ein binäres Dateiformat) oder Anforderungen eines Bit-Level-Standards (Netzwerkpakete oder Befehls-Opcodes).
Ein reales Beispiel ist, als NeXT den xnu Kernel von der Motorola 68000 (m68k) Architektur auf die i386 Architektur portierte. NeXT hatte eine funktionierende m68k-Version ihres Kernels. Als sie es nach i386 portierten, stellten sie fest, dass sich die Ausrichtungsanforderungen des i386 von denen der m68k so unterschieden, dass eine m68k-Maschine und eine i386-Maschine sich nicht auf das Layout der herstellerspezifischen BOOTP-Struktur von NeXT einigen konnten.Um das i386-Strukturlayout mit dem m68k übereinstimmen zu lassen, fügten sie ein unbenanntes Bitfeld der Länge Null hinzu, um die -Struktur mit 16-Bit-Ausrichtung zu erzwingen.
Hier sind die relevanten Teile aus dem Mac OS X 10.6.5 xnu Quellcode:
/* from xnu/bsd/netinet/bootp.h */
/*
* Bootstrap Protocol (BOOTP). RFC 951.
*/
/*
* HISTORY
*
* 14 May 1992 ? at NeXT
* Added correct padding to struct nextvend. This is
* needed for the i386 due to alignment differences wrt
* the m68k. Also adjusted the size of the array fields
* because the NeXT vendor area was overflowing the bootp
* packet.
*/
/* . . . */
struct nextvend {
u_char nv_magic[4]; /* Magic number for vendor specificity */
u_char nv_version; /* NeXT protocol version */
/*
* Round the beginning
* of the union to a 16
* bit boundary due to
* struct/union alignment
* on the m68k.
*/
unsigned short :0;
union {
u_char NV0[58];
struct {
u_char NV1_opcode; /* opcode - Version 1 */
u_char NV1_xid; /* transcation id */
u_char NV1_text[NVMAXTEXT]; /* text */
u_char NV1_null; /* null terminator */
} NV1;
} nv_U;
};
C99 ermöglicht Arrays mit einer Länge von Null, um dynamisch große Strukturen besser zu unterstützen. – falstro
@roe: Ja, nun, es ist das Äquivalent von dynamisch zugewiesenen Arrays mit einer Länge von 0, die wirklich nützlich sind. Ich denke, dass das Problem hier ist, dass die Bitfeldlänge eine Kompilierzeitkonstante sein muss. –
@roe: Ihr Kommentar ist falsch. C ** erlaubt ** 'char a [0];' in keiner Version des Standards. Auf der anderen Seite ist 'char a [];' in Strukturen in C99 erlaubt; Es heißt ein flexibles Array-Mitglied und muss am Ende erscheinen. 'char a [];' ist ** nicht ** eine "Kurzschrift für' char a [0]; '". –