我宣布了两个工会
typedef union
{
struct
{
unsigned short n1 : 4;
unsigned int n2 : 4;
} s;
unsigned int val;
} unionA;
typedef union
{
struct
{
unsigned int n1 : 4;
unsigned int n2 : 4;
} s;
unsigned int val;
} unionB;
我将相同的值分配给
val
作为
unionA uA;
unionB uB;
uA.val = 0xba;
uB.val = 0xba;
我预计在这两种情况下,第一个半字节(由 n1 表示)为
0xa
,第二个半字节(由 n2 表示)为 0xb
。但是,它仅在 0xb
中是 unionB
。在0xc
中是unionA
。
我在 Windows 11 上运行 Visual Studio 2019。
我的理解是,无论位域的数据类型如何,行为都必须相同。是什么导致了这种差异?
C++ 中的联合与 C 中的联合不同。在 C++ 中,任何时候都只有一个成员active,并且从非活动成员读取是未定义的。来自cppreference:
联合体的大小至少要达到容纳其最大数据成员所需的大小,但通常不会更大。其他数据成员旨在分配在与该最大成员的一部分相同的字节中。该分配的细节是实现定义的,但所有非静态数据成员都将具有相同的地址(C++14 起)。从不是最近写入的联合成员中读取是未定义的行为。
自从
std::variant
(c++17) 被引入以来,我不知道联合的使用。联合的目的是为了安全记忆,而不是双关语。