为什么结构体和联合体的大小不匹配?

10

我已经声明了一个联合体,将4100个字节分配给"sample_union"变量,并将相同的联合声明作为结构的一部分,该结构正在分配4104个字节。

union test_size_union {
    struct {
        uint8_t type;
        union {
            uint8_t count;
            uint8_t list;
        };
        uint16_t rc;
        uint16_t arr_value[2048];
    };
    uint64_t first_dword;
}__attribute__((packed)) sample_union ;

将上述联合体放置在结构体内会分配 4104 字节。

struct test_size_struct {
    union {
        struct {
            uint8_t type;
            union {
                uint8_t count;
                uint8_t list;
            };
            uint16_t rc;
            uint16_t arr_value[2048];
        };
        uint64_t first_dword;
    };
}__attribute__((packed)) sample_struct;

好的,这不是一个项目要求,但我想知道为什么编译器对这两个声明的行为不同。

gcc版本:(GCC)4.9.2,x86_64

平台:Linux,x86_64


请注意,C++标准不允许使用匿名结构体(GCC提供了该扩展功能)。 - eerorika
1
@JoachimPileborg:该数组的类型为uint16_t[2048],因此在大多数机器上占用4096字节。 - DarkDust
2
@user50 不要在评论中发布多行代码;而是编辑您的问题。 - user694733
1
重新表达我的原始评论:联合体内部的结构体没有被打包。 - Some programmer dude
2
实际上,在这种情况下,打包一个联合体是有意义的。未打包的联合体具有一些填充,因此其大小是8(sizeof(uint64_t))的倍数。打包的联合体则不会有填充。 - Martin Bonner supports Monica
显示剩余4条评论
1个回答

11

当您将联合体放置在结构体内时,您没有将union标记为packed。未压缩的联合体有一些填充(四个字节),以使其大小成为uint64_t大小的倍数。

压缩的联合体不具备此填充,因此它更小。

另外需要注意的是,在联合体内部的匿名结构体没有标记packed。在这种情况下没有关系,因为一切都很好地对齐了 - 但这也是需要注意的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接