为什么这个UNION像一个结构体?

Spa*_*ott 7 c struct unions

我遇到了一些具有联合的代码(它位于 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));
}
Run Code Online (Sandbox Code Playgroud)

它应该是所有成员中最大的,每个成员只有8位。

引起我注意并促使我对此进行调查的代码是:

STAT.BC9 = 0;
STAT.BC8 = 0;
STAT.Val |= byteToSend;
Run Code Online (Sandbox Code Playgroud)

第三行合并到第一行和第二行的值中。

所以我想测试一下,结果是 4 个字节,而不是 1 个字节。我什至在几个不同的编译器中测试了它(因此 MS Visual C 使用#pragma)。

每个成员都是 8 位,最后两个结构重叠,将 PID 值放置在同一内存位置。然而,无论我使用编译器来评估它,这都是 4 个字节。

向联合添加结构的行为是否存在某些问题?

任何解释表示赞赏。

dbu*_*ush 6

虽然 C 标准中没有明确指定,但位域通常会占用与其声明的基类型相对应的单元。

在这种情况下,所有位域都被声明为unsigned. 该类型在您的系统上可能为 4 个字节,因此位域占用该类型的一个单元。

如果将字段的类型更改为unsigned charor ,uint8_t它们应该只占用一个字节。请注意,这假设您的编译器允许将这些类型用于位域,尽管大多数编译器都这样做。


klu*_*utt 5

C有隐式类型的概念。因此unsigned将声明一个unsigned int. 但事情变得更奇怪了。const如果您只使用or static/ ,情况也是如此auto

const x = 5; // Declares a const int variable
static x;    // Declares a static int variable
const static unsigned x = 5; // Declares a const static unsigned int variable
Run Code Online (Sandbox Code Playgroud)

你想要的是一个unsigned char.

它应该是所有成员中最大的,每个成员只有8位。

它至少应该是这个尺寸。没有什么可以阻止它变得更大。