在C11,下面的結構工作的一個錯誤:在GCC實現位字段
struct S {
unsigned a : 4;
_Bool b : 1;
};
獲取由GCC奠定了由此使用4位的unsigned
(4字節),接着是_Bool
(4字節),其中使用1位,總大小爲8字節。
請注意,C99和C11明確允許_Bool
作爲位域成員。在C11標準(也可能是C99太)也正在§6.7.2.1「結構和聯合說明」¶11指出:
實現可分配任何可尋址存儲單元,大到足以容納一個位字段。如果剩餘足夠的空間,緊接在結構中的另一位字段之後的位字段應被打包到相同單元的相鄰位中。
因此,我相信構件上方b
應已包裝成分配用於所述構件a
存儲單元中,從而導致總的大小4個字節的結構。
GCC正確的行爲,並使用相同類型的兩個成員時,確實發生了包裝,或者當一個unsigned
和其他signed
,但類型unsigned
和_Bool
似乎被認爲是由GCC它來處理它們太明顯正確。
有人可以證實我對標準的解釋,這確實是一個GCC錯誤?
我也對解決方法感興趣(一些編譯器開關,編譯指示,__attribute__
...)。
我使用gcc 4.7.0與-std=c11
(儘管其它設置顯示相同的行爲。)
請注意,GCC擴展'__attribute__((packed))'可以應用於這裏的成員,但與此問題正交(它導致大小爲4 + 1 = 5的結構,即具有相同的問題。) – ndkrempel
相關:http://stackoverflow.com/questions/308364/c-bitfield-packing-with -bools(但是指的是C++,它在位域上的表述並不盡如人意)。 – ndkrempel
根據上面鏈接問題的答案,這種行爲在gcc 4.2.4中沒有發生,所以可能是從那時起迴歸。 – ndkrempel