2

次の C++ コードがあるとします。

struct something
{
  // ...
  union { int size, length; };
  // ...
};

structこれにより、同じ値にアクセスする の 2 つのメンバー、 と が作成sizeされますlength

2 つのメンバーを完全なエイリアスとして扱うこと (つまり、サイズを設定してから長さにアクセスする、またはその逆) は未定義の動作になりますか? このタイプの動作を実装する「より良い」方法はありますか、またはこれは受け入れられる実装ですか?

4

3 に答える 3

5

はい、これは許可されており、明確に定義されています。§3.10 [basic.lval] によると:

10/プログラムが、次の型以外の glvalue を介してオブジェクトの格納された値にアクセスしようとした場合、動作は未定義です。

— オブジェクトの動的タイプ

[...]

ここでは を格納し、intを介して読み取るためint、オブジェクトと同じ動的型の glvalue を介してオブジェクトにアクセスするため、問題はありません。


同じ接頭辞を共有する構造について、規格には特別な警告さえあります。または、標準では、共通の初期シーケンスを共有する標準レイアウト タイプです。

§9.2/18標準レイアウト共用体に、共通の初期シーケンスを共有する 2 つ以上の標準レイアウト構造体が含まれている場合、および標準レイアウト共用体オブジェクトに現在これらの標準レイアウト構造体の 1 つが含まれている場合、共通の構造体を検査することが許可されます。それらの最初の部分。2 つの標準レイアウト構造体は、対応するメンバーがレイアウト互換の型を持ち、どちらのメンバーもビット フィールドではないか、両方が 1 つ以上の初期メンバーのシーケンスに対して同じ幅のビット フィールドである場合、共通の初期シーケンスを共有します。

あれは:

struct A { unsigned size; char type; };
struct B { unsigned length; unsigned capacity; };

union { A a; B b; } x;

assert(x.a.size == x.b.length);

編集:intそれが a struct(または a )ではないことを考えると、class実際には正式に定義されていないのではないかと思います (私は確かに標準で何も見ることができませんでした) が、実際には安全であるはずです...問題を isocpp フォーラムに持ち込みました; 穴を見つけたかもしれません。

編集:上記の議論に続いて、§3.10/10 が表示されました。

于 2013-03-07T17:40:32.420 に答える