在这个答案的评论中,据说使用如下的联合将整数分成它们的字节是未定义的行为。在那个地方给出的代码与此相似但不完全相同,如果我更改了代码的未定义行为相关方面,请注明。
union addr {
uint8_t addr8[4];
uint32_t addr32;
};
到目前为止,我认为这将是一种很好的方法来做类似的事情addr = {127, 0, 0, 1};
并获得相应 uint32_t
的回报。(我承认这可能会根据我的系统的字节顺序产生不同的结果。但是问题仍然存在。)
这是未定义的行为吗?如果是这样,为什么?(我不知道C++ 中的 UB 是什么意思是访问非活动的工会成员。)
C99
- 在这一点上,C99 显然非常接近 C++03。
C++03
- 在一个联合中,任何时候最多有一个数据成员处于活动状态,即任何时候最多可以有一个数据成员的值存储在一个联合中。C++03,第 9.5 节 (1),第 162 页
然而
- 如果一个 POD 联合包含多个共享一个公共初始序列的 POD 结构 [...],则允许检查任何 POD 结构成员的公共初始序列,同上。
- 如果两个 POD-struct [...] 类型具有相同数量的非静态数据成员,则它们是布局兼容的,并且相应的非静态数据成员(按顺序)具有布局兼容类型C++03,第 9.2 (14) 节,第 157 页
- 如果两个类型 T1 和 T2 是同一类型,则 T1 和 T2 是布局兼容类型。C++03,第 3.9 (11) 节,第 53 页
结论
- as
uint8_t[4]
和uint32_t
不是同一类型(我猜,一个严格的别名)(加上两者都不是 POD-structs/union)上面确实是 UB?
C++11
- 请注意,聚合类型不包括联合类型,因为具有联合类型的对象一次只能包含一个成员。C++11,脚注 46,第 42 页