工会用法和混乱的代码
Union usage and messy code
我有一些关于联合用法的代码,如下所示:
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 nn",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 nn",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 nn",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 nn",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,"hello"(不起作用?
严格按照标准类型双关语期望在狭窄的情况下是未定义的行为,但在实践中许多编译器都支持它,例如 gcc 手册点在这里用于类型双关语和 -fstrict-aliasing 部分是说:
从与最近写信给的工会成员不同的工会成员那里阅读(称为"类型双关语"(的做法很常见。即使使用 -fstrict-aliasing,也允许类型双关,前提是通过联合类型访问内存。
如果您打算大量使用类型双关语,我建议您阅读了解严格别名。
y.b
的值b
,因为联合的所有元素共享内存,并且您使用 ASCII 中b
100
初始化了y
。这与修改一个字段时x
其他字段(包括strcpy
的情况(发生变化的原因相同,并且根据您的编译器,这可能是未定义的或定义良好的(在 gcc 的情况下,它是定义的(。
为完整起见,C++标准草案第1款9.5
第1款说(强调我的(:
在联合中,最多一个非静态数据成员可以随时处于活动状态,也就是说,最多一个非静态数据成员的值可以随时存储在联合中。[ 注意:为了简化联合的使用,有一个特殊的保证:如果标准布局联合包含多个共享公共初始序列 (9.2( 的标准布局结构,并且如果此标准布局联合类型的对象包含标准布局结构之一,则允许检查任何标准布局结构成员的公共初始序列;请参阅 9.2.—尾注 ] 联合的大小足以包含其最大的非静态数据成员。每个非静态数据成员都像是结构的唯一成员一样分配。
如果您看到 ASCII 表,您将看到值100
与字符 'd'
相同。
你必须记住,工会的所有成员都共享相同的记忆。这意味着,如果你设置了一个工会成员,所有成员都会改变,而且并不总是可以理解。因此,写入一个成员并从另一个成员读取是未定义的行为。
strcpy(x.b,"hello")
确实有效,因为你可以看到x
工会的所有成员在你这样做后都会发生变化。
你的代码有UB(未定义的行为(;分配给联合的一个成员,然后检查另一个成员是非法的(具有相同初始成员的POD结构的特殊情况除外(。
在分配给 x.a
之前读取未初始化的值(例如任何x
字段(也是非法的。
我认为当你说int a时,你分配sizeof(int(,通常是32位。但是当你说 char[10] 时,你正在分配 10 * sizeof(char( 字节!!(10 * 4 位(这两者不能互相投射。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 智能手机代码厨师问题逻辑混乱
- 为什么我在有关文件编码格式的QT代码中获得了混乱的代码
- 为什么使用valgrind时管道会变得混乱的代码 --xml-fd
- 工会用法和混乱的代码
- typedef 在C++代码混乱中
- 混乱的模板代码
- 组织sqlite3 C/ c++预处理语句(避免全局代码混乱)