C语言中联合数组的合法访问方式咨询
C语言中联合数组的合法访问方式咨询
嘿,咱们来聊聊你这个联合数组的访问问题哈~
首先先复盘下你的场景:你定义了这么一个联合类型:
typedef union { uint64_t ulong; uint32_t uint[2]; } myunion_t;
接着创建了一个包含3个该联合元素的数组myunion_t myarray[3];,而且你已经明确知道用printf("%u", myarray[2].uint[1]);来访问最后一个uint元素是完全合法的。现在你想问的应该是类似“通过取ulong成员的地址,强制转换成uint32_t*后访问第二个元素”这类操作是否合法对吧?
那我给你掰扯清楚:
- 先讲合法的情况:你用
myarray[2].uint[1]直接访问的方式,完全符合C标准的规定。因为C标准明确允许通过联合来做类型双关——联合的所有成员共享同一块内存空间,不管你之前是给uint数组赋的值,还是给ulong赋的值之后想用uint来解析内存内容,这种直接访问联合成员的方式都是合法的。 - 再说说不合法的情况:如果是像
*( (uint32_t *)&myarray[2].ulong + 1 )这种操作,那就踩坑了。这违反了C标准里的严格别名规则——简单说就是,除非是用字符类型指针,否则你不能用一个指针类型去访问另一种不兼容类型的对象。uint64_t和uint32_t属于不兼容类型,所以这种强制转换指针后解引用的行为是未定义行为,编译器可能会生成和你预期不符的代码,甚至在不同优化等级下表现完全不一样。
另外补充个小细节:字节序会影响uint[1]对应ulong的哪部分内容(小端是高32位,大端是低32位),但不管字节序如何,直接访问联合成员的方式都是合法的,这点不用担心。
备注:内容来源于stack exchange,提问作者Simon Goater
相关产品推荐
相关产品推荐

