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

The standard says that reading from any element in a union other than the last one written is undefined behavior. In theory, the compiler could generate code which somehow kept track of the reads and writes, and triggered a signal if you violated the rule (even if the two are the same type). A compiler could also use the fact for some sort of optimization: if you write to a (or x), it can assume that you do not read b (or v[0]) when optimizing.

In practice, every compiler I know supports this, if the union is clearly visible, and there are cases in many (most?, all?) where even legal use will fail if the union is not visible (e.g.:

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 );

I've actually seen this fail with g++, although according to the standard, it is perfectly legal.)

Also, even if the compiler supports writing to Point::x and reading from Point::v[0], there's no guarantee that Point::y and Point::v[1] even have the same physical address.

于 2013-06-24T10:41:43.993 回答
0

该标准要求在联合中“分配每个数据成员,就好像它是结构的唯一成员一样”。(9.5)

它还要求struct { float x, y; }并且float v[2]必须具有相同的内部表示(9.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 回答