私が使っているgcc x86コンパイラでは、ビットフィールドはLSBからMSBに割り当てられます(下記参照)。 「生の」レイアウトも表示されます。
7 0
+---+---+---+---+---+---+---+---+
| padding | b | a |
+---+---+---+---+---+---+---+---+
7 0
+---+---+---+---+---+---+---+---+
| raw |
+---+---+---+---+---+---+---+---+
あなたは8
7 0
+---+---+---+---+---+---+---+---+
| padding | b | a |
+---+---+---+---+---+---+---+---+
0 1 0 0 0 1 0 1
しかし、その後== 1、B == 2とパディング==(0x45)01000101bする生設定した場合、どのようなMSBからコンパイラ割り当てられたビットフィールドの場合LSBに?
7 0
+---+---+---+---+---+---+---+---+
| a | b | padding |
+---+---+---+---+---+---+---+---+
7 0
+---+---+---+---+---+---+---+---+
| raw |
+---+---+---+---+---+---+---+---+
さて、あなたは(0x45)01000101bする生設定した場合、その後== 0、B == 2とパディング== 5.
7 0
+---+---+---+---+---+---+---+---+
| a | b | padding |
+---+---+---+---+---+---+---+---+
0 1 0 0 0 1 0 1
あなたのコンパイラがレイアウトする方法を理解していればどのようにビットフィールドを割り当てるかについては、これを利用することができますが、これは移植性がないことに注意してください。私は組み込みソフトウェア分野で働いており、私たちはこれを常に利用しています。
あなたのコードでは、 ':1'、':2'と ':5'のビットフィールドが重なり合っています。つまり、' padding'は何も埋められません。おそらく、あなたはgoogle "punning C++"とバックグラウンド読んでください。 * "なぜ最近"ではなかった組合のメンバーから読み込むのが未定義なのか不思議です。 "* - ポインタやポインタへの参照のみを使って変数が書き込まれると仮定すると、コンパイラはより積極的に最適化できるためです。同じ型(2つの例外を除いて)。 –
'その割り当ての詳細は実装定義です' - コンパイラは、あなたが格納されているデータを読むことを期待するような方法でコードを最適化することができます。例えば 'b'に格納されたデータ'b'からのみ読み込まれ、' raw'や 'a'では読み込まれません。これは理論的なケースです。また、メモリ内のビットフィールドのレイアウトは標準では指定されていないことに注意してください。 – ubuntugod
@TonyDご返信ありがとうございます。私の例ではバグです。一定。重複はありません。 – Hei