C11 での作業、次の構造体:
struct S {
unsigned a : 4;
_Bool b : 1;
};
unsigned
4 ビットが使用される (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
います (ただし、他の設定は同じ動作を示します)。