この回答のコメントでは、次のようなユニオンを使用して整数をバイトに分割することは未定義の動作になると言われています。その場所で提供されているコードは、これと同じではありませんが、類似しています。コードの未定義の動作関連の側面を変更した場合は、メモしてください。
union addr {
uint8_t addr8[4];
uint32_t addr32;
};
addr = {127, 0, 0, 1};
これまでは、これは次のようなことを行い、対応する ものを取得するための優れたアプローチであると考えていuint32_t
ました。(システムのエンディアンによって異なる結果が生じる可能性があることは認めますが、問題は残ります。)
これは未定義の動作ですか?もしそうなら、なぜですか?( C++ の UB とは、非アクティブな共用体メンバーにアクセスすることを意味するかどうかはわかりません。 )
C99
- この点では、C99 は明らかに C++03 にかなり近いです。
C++03
- 共用体では、いつでもアクティブにできるデータ メンバーは最大 1 つです。つまり、データ メンバーの最大 1 つの値をいつでも共用体に格納できます。C++03、セクション 9.5 (1)、162 ページ
でも
- POD 共用体に共通の初期シーケンスを共有する複数の POD 構造体が含まれる場合 [...]、POD 構造体メンバーのいずれかの共通の初期シーケンスを検査することが許可されます。
- 2 つの POD 構造体 [...] 型は、同じ数の非静的データ メンバーを持ち、対応する非静的データ メンバーが (順番に) レイアウト互換型を持つ場合、レイアウト互換性がありますC++03、セクション 9.2 (14)、 157ページ
- T1 と T2 の 2 つの型が同じ型である場合、T1 と T2 はレイアウト互換型です。C++03、セクション 3.9 (11)、53 ページ
結論
- as
uint8_t[4]
とuint32_t
は同じタイプではありません (厳密なエイリアシングだと思います) (さらに、どちらも POD 構造体/共用体ではありません) 上記は実際に UB ですか?
C++11
- ユニオン型のオブジェクトには一度に 1 つのメンバーしか含めることができないため、集約型にはユニオン型が含まれないことに注意してください。C++11、脚注 46、42 ページ