【发布时间】:2021-11-08 19:25:28
【问题描述】:
我遇到了一些具有联合的代码(它位于 Microchip 的库中)。
一切都很好,直到我看到它为工会的不同成员分配了价值一个接着一个。我的直接想法是“他们在写同一个位置......” 然后我决定做一个测试。根据我认为我理解的每一项措施,这个联合应该是一个字节(8 位)。但它不是……它是 4 个字节。
#pragma pack(1)
typedef union _STATUS
{
BYTE Val;
struct {
unsigned BC8 : 1;
unsigned BC9 : 1;
unsigned BSTALL : 1;
unsigned DTSEN : 1;
unsigned INCDIS : 1;
unsigned KEN : 1;
unsigned DTS : 1;
unsigned UOWN : 1;
};
struct {
unsigned BC8 : 1;
unsigned BC9 : 1;
unsigned PID0 : 1;
unsigned PID1 : 1;
unsigned PID2 : 1;
unsigned PID3 : 1;
unsigned : 1;
unsigned UOWN : 1;
};
struct {
unsigned : 2;
unsigned PID : 4;
unsigned : 2;
};
} STATUS;
void PrintIt() {
printf("Size of UNION is %d \n", sizeof(STATUS));
}
它应该是所有成员中最大的,每个成员只有8位。
引起我注意并让我对此进行调查的代码是:
STAT.BC9 = 0;
STAT.BC8 = 0;
STAT.Val |= byteToSend;
第三行合并到第一行和第二行的值。
所以我想测试它,它是 4 个字节,而不是一个。我什至在几个不同的编译器中对其进行了测试(因此#pragma 用于 MS Visual C)。
每个成员正好是 8 位,最后两个结构重叠以将 PID 值放在相同的内存位置。然而,我使用编译器评估它的每种方式都是 4 个字节。
向联合中添加结构的行为有什么问题吗?
感谢任何解释。
【问题讨论】:
-
union _STATUSsigh...你会认为到 2021 年,人们终于习惯了typedef union NAME { ... } NAME;- 这是完全合法、方便且不'不需要踩保留标识符。 -
相当肯定在联合的匿名结构中定义了两次相同的成员是 UB...
-
@StoryTeller-UnslanderMonica 不是我的代码。问题是关于存储大小,而不是声明语法。
-
这就是我发表评论而不是答案的原因
-
您的编译器不会抱怨
BC8、BC9和UOWN的重新定义。 GCC、Clang 和 MSVC 会报错,那么你是如何在“几种不同的编译器”中测试这段代码的呢?