【发布时间】:2019-12-08 07:24:13
【问题描述】:
我有以下工会:
union PM_word {
uint8_t u8[8];
uint16_t u16[4];
uint32_t u32[2];
uint64_t u64[1];
};
假设我初始化这个联合的一个实例如下:
PM_word word;
word.u32[0] = 0;
word.u16[2] = 1;
word.u8[6] = 2;
word.u8[7] = 3;
如果我理解正确,尝试读取word.u32[1] 是未定义的行为,因为已设置的word.u16 和word.u8 的元素与其重叠。但是,读取word.u32[0] 是否也是未定义的行为?
编辑: 也重新标记了 C++。如果 C 和 C++ 的语义在这个问题上有所不同,非常感谢有关 C 和 C++ 的答案。
【问题讨论】:
-
如果你没有明确设置值,它的值将是未定义的。
-
由于内存重叠,改变u16或u8意味着读取u32是未定义的。在实践中,您仍然可以读取 u32,根据您设置的 u16 和 u8 值,它可能会有所帮助。
-
它真正依赖于平台。不同的计算机会以不同的方式排列内存,因此您将从 u32 读回的实际值会因特定计算机而异
-
据我在 C++ 中的理解,你不能这样做。您必须将一个数组
memcpy放入您想要访问它的任何数组中,以便在 C++ 中定义行为。 C++ 不做类型双关语。 -
C 和 C++ 在这一点上有所不同。您不应在一个问题中同时标记两者。