Arbeiten in C11, die folgende Struktur:Ein Fehler in GCC Implementierung von Bitfeldern
struct S {
unsigned a : 4;
_Bool b : 1;
};
wird von GCC als ein unsigned
(4 Bytes), davon 4 Bits werden verwendet, gefolgt von einem _Bool
layed out (4 Bytes), von denen 1 Bit verwendet wird, für eine Gesamtgröße von 8 Bytes.
Beachten Sie, dass C99 und C11 speziell _Bool
als Bitfeldelement zulassen. Der C11-Standard (und wahrscheinlich C99 auch) heißt es auch unter §6.7.2.1 ‚Struktur und Vereinigung Bezeich‘ ¶11 dass:
Eine Implementierung jede adressierbare Speichereinheit zuweisen kann groß genug, um ein Bit-Feld zu halten. Wenn genügend Speicherplatz vorhanden ist, sollte ein Bitfeld, das unmittelbar einem anderen Bitfeld in einer Struktur folgt, in benachbarte Bits derselben Einheit gepackt werden.
Deshalb glaube ich, dass das Mitglied b
oben in die Speichereinheit für das Element a
zugeordnet verpackt worden sein, in einer Struktur von Gesamtgröße 4 Byte ergibt.
GCC verhält sich korrekt und Verpackung auftritt, wenn die gleichen Typen für die beiden Mitglieder, oder wenn man unsigned
und die andere signed
, aber die Typen unsigned
und _Bool
scheinen zu verschieden zu betrachten, von GCC für sie mit ihnen umgehen korrekt.
Kann jemand meine Interpretation des Standards bestätigen, und das ist in der Tat ein GCC-Fehler?
Ich bin auch interessiert an einem Workaround (einige Compiler-Schalter, Pragma, __attribute__
...).
Ich bin mit gcc 4.7.0 mit -std=c11
(obwohl anderen Einstellungen das gleiche Verhalten zeigen.)
Beachten Sie, dass die GCC-Erweiterung '__attribute__ ((gepackt))' hier auf die Mitglieder angewendet werden kann , ist aber orthogonal zu diesem Problem (es ergibt sich eine Struktur der Größe 4 + 1 = 5, dh mit dem gleichen Problem.) – ndkrempel
Related: http://stackoverflow.com/questions/308364/c-bitfield-packing-with -bols (bezieht sich aber auf C++, das in Bitform-Feldern nicht ganz so genau formuliert ist.) – ndkrempel
Laut einer Antwort auf die oben verlinkte Frage trat dieses Verhalten in gcc 4.2.4 nicht auf, so kann es sein eine Regression seither. – ndkrempel