我有一些关于union的用法的代码,如下所示:
int main(){
typedef union{int a;char b[10];float c;}Union;
Union x,y = {100};
printf("Union x :%d| |%s| |%f \n",x.a,x.b,x.c );
printf("Union y :%d| |%s| |%f \n\n",y.a,y.b,y.c);
x.a = 50;
printf("Union x :%d| |%s| |%f \n",x.a,x.b,x.c );
printf("Union y :%d| |%s| |%f \n\n",y.a,y.b,y.c);
strcpy(x.b,"hello");
printf("Union x :%d| |%s| |%f \n",x.a,x.b,x.c );
printf("Union y :%d| |%s| |%f \n\n",y.a,y.b,y.c);
x.c = 21.50;
printf("Union x :%d| |%s| |%f \n",x.a,x.b,x.c );
printf("Union y :%d| |%s| |%f \n\n",y.a,y.b,y.c);
return 0;
}
在编译并执行上面的代码之后,我得到了这样的结果:
Union x :0| || |0.000000
Union y :100| |d| |0.000000
Union x :50| |2| |0.000000
Union y :100| |d| |0.000000
Union x :1819043176| |hello| |1143141483620823940762435584.000000
Union y :100| |d| |0.000000
Union x :1101791232| || |21.500000
Union y :100| |d| |0.000000
我不知道为什么y.b被初始化为“d”?为什么x.a和x.c的值在之后改变了?为什么strcpy(x.b,“你好”)不起作用?
答案 0 :(得分:3)
严格来说,标准的 type-punning 在狭窄的情况下是undefined behavior,但实际上很多编译器都支持它,例如gcc manual points here for type-punning和 -fstrict-aliasing 部分说:
从不同的工会成员阅读的做法比最近写的那个(称为“打字式”)很常见。即使使用-fstrict-aliasing,只要通过union类型访问内存,就允许类型为punning。
如果您计划大量使用 type-punning ,我建议您阅读Understanding Strict Aliasing。
y.b
的值为b
,因为联合的所有元素共享内存并且您使用y
初始化100
,其中 ASCII 是b
。这就是为什么x
的其他字段在修改strcpy
的情况下会发生变化的原因,包括9.5
的情况,并且取决于您的编译器,这可能是未定义的或定义良好的(在gcc的情况下它被定义)。
为了完整起见,C ++草案标准部分{{1}} 联盟段 1 表示(强调我的):
在联合中,最多一个非静态数据成员可以随时处于活动状态,也就是说,最多可以存储一个非静态数据成员的值在任何时候的工会。 [注意:为了简化联合的使用,我们做了一个特别的保证:如果标准布局联合包含几个共享一个共同初始序列(9.2)的标准布局结构,那么如果是这个标准的对象 - layout union type包含一个标准布局结构,允许检查任何标准布局结构成员的公共初始序列;见9.2。 -end note] union的大小足以包含其最大的非静态数据成员。每个非静态数据成员都被分配,就像它是结构的唯一成员一样。
答案 1 :(得分:2)
如果您看到ASCII table,则会看到值100
与字符'd'
相同。
您必须记住,联盟的所有成员共享相同的内存。这意味着如果您设置了一个联盟的一个成员,所有成员都会更改,而不是总是可以理解的。因此,写入一个成员并从另一个成员读取是未定义的行为。
并且strcpy(x.b,"hello")
确实有效,因为您可以看到x
联盟的所有成员在您这样做后发生了变化。
答案 2 :(得分:2)
您的代码有UB(未定义的行为);分配给一个工会的一个成员然后检查另一个成员是非法的(除了具有相同初始成员的POD结构的特殊情况)。
在分配到x
之前,读取未初始化的值(例如x.a
的任何字段)也是非法的。
答案 3 :(得分:-2)
我认为当你说int时,你会分配sizeof(int),一般是32位。 但是当你说char [10]时,你正在分配10 * sizeof(char)字节!! (10 * 4位) 这两者不能相互融合。