只是阅读一些匿名结构以及它是如何不标准的,并且它的一些一般用例是未定义的行为......
这是基本情况:
struct Point {
union {
struct {
float x, y;
};
float v[2];
};
};
所以写入x然后从v [0]读取将是未定义的,因为你会期望它们是相同的,但可能不是这样。
不确定这是否属于同一类型的标准联盟...
union{ float a; float b; };
是否未定义写入a然后从b读取?
也就是说,标准是否有关于数组的二进制表示和相同类型的顺序变量的说法。
答案 0 :(得分:6)
标准说从联盟中的任何元素读取其他元素
比写的最后一个是未定义的行为。在理论上,
编译器可以生成以某种方式跟踪的代码
读取和写入,并在您违反时触发信号
规则(即使两者是同一类型)。编译器也可以
使用这个事实进行某种优化:如果你写信给a
(或x
),可以假设您没有阅读b
(或v[0]
)
在优化时。
实际上,我所知道的每个编译器都支持这个, if union 是清晰可见的,有很多案例(大多数?,全部?) 如果工会不可见,即使合法使用也会失败 (例如:
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::y
并且Point::v[1]
甚至具有相同的物理地址。
答案 1 :(得分:0)
标准要求在联合中“[e] ach数据成员被分配,就好像它是结构的唯一成员一样。” (9.5)
它还要求struct { float x, y; }
和float v[2]
必须具有相同的内部表示(9.2),因此您可以安全地重新解释转换为另一个
将这两条规则结合在一起可以保证您描述的union
能够正常运行,只要它真正写入内存即可。但是,因为标准只要求写入的最后一个数据成员有效,所以如果联合仅用作局部变量,理论上可能会使实现失败。然而,如果真的发生了,我会感到惊讶。
答案 2 :(得分:-5)
我不明白为什么你使用了浮动v [2];
点结构的简单并集可以定义为:
union{
struct {
float a;
float b;
};
} Point;
您可以在unioin中访问值:
Point.a = 10.5;
point.b = 12.2; //example