结构的大小 - 填充和对齐

Size of structure - padding and alignment

我有一个明确大小的结构如下:

typedef struct
{
    unsigned long                   A : 4;
    unsigned long                   B : 12;
    union
    {
        unsigned long               C1 : 8;
        unsigned long               C2 : 8;
        unsigned long               C3 : 8;
    };
    unsigned long                   D : 8;
}FooStruct;

这个结构体的总大小理论上应该是32bit(4字节)。但是,我使用 sizeof 得到了 12 字节的大小,所以这里应该有一些填充和对齐。

我只是不明白为什么以及在哪里。谁能给我解释一下这个结构是如何占用 12 个字节的内存的?

联合强制开始一个新的无符号长整数,联合之后的成员又是一个无符号长整数。假设 long 是 4 个字节,这意味着你的结构将有 3 个无符号 long,总共 12 个字节。虽然由三个同样大小的成员组成的工会也显得很奇怪。

如果您希望它的大小为 4 个字节,为什么不将其更改为:

typedef struct
{
    unsigned short                   A : 4;
    unsigned short                   B : 12;

    union
    {
        unsigned char               C1 : 8;
        unsigned char               C2 : 8;
        unsigned char               C3 : 8;
    };

    unsigned char                   D : 8;
}FooStruct;

此外,如果您使用的是 gcc 并且想要禁用结构填充,您可以使用 __attribute__((packed)):

struct FooStruct
{
    unsigned long                   A : 4;
    unsigned long                   B : 12;
    union
    {
        unsigned long               C1 : 8;
        unsigned long               C2 : 8;
        unsigned long               C3 : 8;
    } __attribute__((packed)) C;
    unsigned long                   D : 8;
} __attribute__((packed));

但请注意,某些架构可能会对未对齐的数据访问进行处罚或根本不允许。