C11 での作業、次の構造体:
struct S {
unsigned a : 4;
_Bool b : 1;
};
unsigned4 ビットが使用される (4 バイト)として GCC によってレイアウトされ、その後_Boolに 1 ビットが使用される (4 バイト) が続き、合計サイズは 8 バイトになります。
C99 と C11 では_Bool、ビット フィールド メンバとして明確に許可されていることに注意してください。C11 標準 (およびおそらく C99 も) は、§6.7.2.1 '構造体および共用体指定子' ¶11 の下で次のように述べています。
実装では、ビットフィールドを保持するのに十分な大きさのアドレス可能なストレージユニットを割り当てることができます。十分なスペースが残っている場合、構造内の別のビットフィールドの直後に続くビットフィールドは、同じユニットの隣接するビットにパックされます。
したがって、b上記のメンバーは、メンバーに割り当てられたストレージユニットにパックされているはずでありa、合計サイズが 4 バイトの構造体になると思います。
GCC は正しく動作し、2 つのメンバーに同じ型を使用する場合、または一方がunsignedで他方が である場合にパッキングが行われますsignedが、型unsignedと_Boolは GCC によって区別されすぎて正しく処理できないと見なされているようです。
誰かが標準の私の解釈を確認できますか?これは実際に GCC のバグです?
また、回避策 (コンパイラ スイッチ、プラグマなど) にも興味があり__attribute__ます。
私は gcc 4.7.0 を使用して-std=c11います (ただし、他の設定は同じ動作を示します)。