大佬教程收集整理的这篇文章主要介绍了将union字段中的位解释为C/C++中的不同数据类型,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
typedef union { uint64_t x; uint32_t y[2]; }test; test testdata; testdata.x = 0xa; printf("uint64_t: %016lx\nuint32_t: %08x %08x\n",testdata.x,testdata.y[0],testdata.y[1]); printf("Addresses:\nuint64_t: %016lx\nuint32_t: %p %p\n",&testdata.x,&testdata.y[0],&testdata.y[1]);
输出是
uint64_t: 000000000000000a uint32_t: 0000000a 00000000 Addresses: uint64_t: 00007ffe09d594e0 uint32_t: 0x7ffe09d594e0 0x7ffe09d594e4
y指向的起始地址与x的起始地址相同.由于两个字段使用相同的位置,x的值不应该是00000000 0000000a吗?
为什么不发生这种情况?内部转换如何在具有不同数据类型的不同字段的联盟中发生?
需要做什么来使用联合以与uint64_t中相同的顺序检索精确的原始位作为uint32_t?
编辑:
正如评论中所提到的,C给出了未定义的行为.
它在C中如何工作?我们真的可以这样做吗?
您正在uint64_t值和2个uint32_t值的数组之间进行类型惩罚.根据结果,您的系统是小端,并且很乐意通过简单地重新解释字节表示来接受类型惩罚.并且0x0a的字节表示为小端uint64_t是:
Byte number 0 1 2 3 4 5 6 7 Value 0x0a 0x00 0x00 0x00 0x00 0x00 0x00 0x00
little endian中的最低有效字节具有最低地址.现在很明显为什么uint32_t [2]表示为{0x0a,0x00}.
但是你所做的只是在C语言中是合法的.
C语言:
C11表示为6.5.2.3结构和工会成员:
95)说明明确说:
因此,即使注释不是规范性的,它们的目的是明确标准应该被解释的方式=>代码是有效的,并且在定义uint64_t和uint32_t类型的小端系统上定义了行为.
C语言:
C部分更严格. C17的草案n4659在[basic.lval]中说明:
注释56明确地说:
因为在C标准中从未引用过双关语,并且因为结构/联合部分不包含C的重新解释的等价物,这意味着在C中读取不是最后写入的成员的值会调用undefined行为.
当然,常见的编译器实现编译C和C,并且大多数它们甚至在C源中也接受C语言,因为gcc C编译器很乐意接受C源文件中的VLA.毕竟,未定义的行为包括预期的结果……但是你不应该依赖它来获取可移植的代码.
以上是大佬教程为你收集整理的将union字段中的位解释为C/C++中的不同数据类型全部内容,希望文章能够帮你解决将union字段中的位解释为C/C++中的不同数据类型所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。