pracujących w C11, następujące struktury:Błąd w realizacji GCC bitowych pól
struct S {
unsigned a : 4;
_Bool b : 1;
};
pobiera rozplanowane przez GCC JAKO unsigned
(cztery bajty), które są wykorzystywane 4 bity, a następnie _Bool
(4 bajty), z których używany jest 1 bit, o łącznej wielkości 8 bajtów.
Należy zauważyć, że C99 i C11 wyraźnie zezwalają na _Bool
jako element pola bitowego. Średnia C11 (i prawdopodobnie też C99) stwierdza również pod §6.7.2.1 „Struktura i unia Specyfikatory” ¶11 że:
implementacja może przeznaczyć dowolną adresowalny moduł pamięci na tyle duże, aby pomieścić nieco pola. Jeśli pozostanie wystarczająca ilość miejsca, pole bitowe, które następuje bezpośrednio po innym polu bitowym w strukturze, zostanie zapakowane w sąsiednie bity tego samego urządzenia.
Więc wierzę, że człon b
powyżej powinny zostały zapakowane do jednostki magazynowej przeznaczonej na członka a
, w wyniku struct całkowitej wielkości 4 bajtów.
GCC zachowuje się poprawnie i pakowania występuje podczas korzystania z tych samych typów dla dwóch członków, lub gdy jeden jest unsigned
a drugi signed
, ale typy unsigned
i _Bool
wydają się być uważany za odrębny przez GCC na to, aby je obsłużyć prawidłowo.
Czy ktoś może potwierdzić moją interpretację standardu, i że jest to rzeczywiście błąd GCC?
Interesuje mnie również obejście (jakaś zmiana kompilatora, pragma, __attribute__
...).
Używam gcc 4.7.0 z -std=c11
(choć inne ustawienia wykazują takie samo zachowanie.)
Należy zauważyć, że rozszerzenie GCC "__attribute__ ((spakowane))" może być stosowane do członków tutaj , ale jest ortogonalny dla tego problemu (powoduje to, że struktura 4 + 1 = 5, czyli z tym samym problemem). – ndkrempel
Powiązane: http://stackoverflow.com/questions/308364/c-bitfield-packing-with -bools (ale odnosi się do C++, co nie jest aż tak wymagające w swoim brzmieniu na polach bitowych). – ndkrempel
Zgodnie z odpowiedzią na pytanie powiązane powyżej, to zachowanie nie wystąpiło w gcc 4.2.4, więc może być regresja od tego czasu. – ndkrempel