7

いくつかの匿名構造について読んだだけで、それが標準ではなく、一般的なユースケースは未定義の動作です...

これは基本的なケースです:

struct Point {
    union {
       struct {
           float x, y;
       };
       float v[2];
    };
};

したがって、書き込みxと読み取りはv[0]、同じであると期待するという点で定義されていませんが、そうではない場合があります。

これが標準かどうかはわかりませんが、同じタイプのユニオンです...

union{ float a; float b; };

aへの書き込みと読み取りは未定義bですか?

つまり、標準は配列のバイナリ表現と同じ型のシーケンシャル変数について何も言っていません。

4

3 に答える 3

7

標準では、最後に書き込まれたもの以外のユニオン内の要素からの読み取りは未定義の動作であると述べています。理論的には、コンパイラーは何らかの方法で読み取りと書き込みを追跡するコードを生成し、ルールに違反した場合 (2 つが同じ型であっても) シグナルをトリガーすることができます。コンパイラは、ある種の最適化のためにこの事実を使用することもできます。(または) に書き込むとa 、最適化時に(または)xを読み取らないと想定できます。bv[0]

実際には、共用体が明確に見える場合、私が知っているすべてのコンパイラがこれをサポートしており、共用体が見えないと合法的な使用でさえ失敗する多くの場合 (ほとんど?, すべて?) があります (例:

union  U { int i; float f; };

int f( int* pi, int* pf ) { int r = *pi; *pf = 3.14159; return r; }

//  ...
U u;
u.i = 1;
std::cout << f( &u.i, &u.f );

g++ でこれが失敗するのを実際に見たことがありますが、標準によれば、これは完全に合法です。)

また、コンパイラが への書き込みとからのPoint::x読み取りをサポートしている場合でも、 と が同じ物理アドレスを持っているというPoint::v[0]保証はありませんPoint::yPoint::v[1]

于 2013-06-24T10:41:43.993 に答える
0

標準では、共用体で「[e]各データ メンバーは、構造体の唯一のメンバーであるかのように割り当てられる」ことが要求されます。(9.5)

また、同じ内部表現 (9.2) を持っstruct { float x, y; }float v[2]いる必要があるため、キャストを安全に再解釈できます。

これら 2 つのルールを組み合わせるとunion、実際にメモリに書き込まれている限り、説明したものが機能することが保証されます。ただし、標準では最後に書き込まれたデータ メンバーが有効であることのみが要求されるため、理論的には、共用体がローカル変数としてのみ使用される場合に実装が失敗する可能性があります。しかし、もしそれが実際に起こったら、私は驚くだろう.

于 2013-06-24T10:56:02.890 に答える
-6

float v[2]; を使用した理由がわかりませんでした。

ポイント構造の単純和集合は、次のように定義できます。

union{

struct {

    float a;
    float b;
};

} Point;

次のように unioin の値にアクセスできます。

Point.a = 10.5; 

point.b = 12.2; //example
于 2013-06-24T10:54:17.573 に答える