2

ユニオンに関するCおよびC++標準を理解している限り、実際に書き込まれたフィールドとは異なるユニオンの特定のフィールドにアクセスしようとすると、技術的に未定義の動作になります。最近、誰かが書いた次のような古いコードを見直しています。

 union myunion {
     float myfloat;
     unsigned int myuint;
 };

 myunion a;
 a.myfloat = 1.01;

 myunion b = a;

一言で言えば、このように共用体で代入演算子を使用することが実際に明確に定義された動作であるかどうかを調べようとしています。このようなコードを自分で作成するときは、ユニオン インスタンスによってアクティブに使用されるフィールドの型を格納し、この値のみを読み書きするようにします。デバッガーでコードをステップ実行すると、これが起こっていることが示されるため、上記の代入演算子を使用すると、おそらくビット単位のコピーになるだけだと思います (この例ではフィールドのサイズが等しいため)。このコードには微妙なバグが見られるので、この方法で共用体を別の共用体に直接割り当てることによって、UB の意味で本質的に危険なものがあるかどうかを知りたいと思っています。

4

2 に答える 2

2

あなたが期待するように。動作は明確に定義されています。

bはaと同じ値になり、myfloatの値は1.01になります。割り当てはビット単位です。「安全な」方法でaとbを比較したい場合は、ビット単位の比較を行うことができます。(operator==floatメンバーでの使用は、安全ではありません。これは、そのうちの1つに実際にfloatが含まれていない場合はUBであるため、および浮動小数点の比較の問題があるためです)。同等性の比較は、実際にはユニオンに対して自動的に定義されないため、オーバーロードを作成する必要があります。

ユニオンには常に、割り当てが機能するようにするrawタイプのみが含まれています。唯一の問題は、型がポインターであり、そのポインターをどこかで管理するかどうかです。次に、このポインタを保持しているユニオンのインスタンスが2つある場合は、注意する必要があります。(ただし、ポインターを含む通常の変数がある場合でも、これは当てはまります)。

于 2013-01-30T12:23:21.343 に答える
2

C++11 より前でunionは、POD (または類似のもの) のみを含めることができました。制限は、ビットごとのコピーが機能するように設計されていました。C++11 では制限の一部が解除されましたが、古い制限に違反した場合、コピーと代入は削除されます (演算子を自分で定義しない限り)。

于 2013-01-30T12:26:04.107 に答える