VS2015中#pragma pack不生效,结构体sizeof结果仍为4字节对齐
问题原因及解决方案
你遇到的问题是因为Visual Studio 2015对带有默认成员初始化器的结构体,会忽略#pragma pack和/Zp的对齐设置。
当你的结构体里写了uint16_t zero = 0;或uint32_t id{};这类类内初始化代码时,编译器会把该结构体判定为非POD类型,而VS2015的#pragma pack和/Zp选项仅对传统POD结构体生效,非POD类型会沿用默认的对齐规则(这里uint32_t的对齐要求是4字节)。
具体到你的代码:
- 带初始化的
Header结构体,即使加了#pragma pack(1),编译器还是会按4字节对齐,所以sizeof(Header)变成8(2字节的zero补2字节对齐,加上4字节的id)。 - 子类
ImageBlock继承Header后,整体对齐要求和基类保持一致(4字节),加上自身的4字节成员,总大小被对齐到12字节(8+4=12,刚好是4的倍数)。
解决办法
去掉结构体里的类内初始化,改用构造函数来初始化成员:
#pragma pack(push,1) struct Header { uint16_t zero; uint32_t id; // 用构造函数初始化 Header() : zero(0), id(0) {} }; struct ImageBlock : Header { uint32_t currentValidLength; ImageBlock() : currentValidLength(0) {} }; #pragma pack(pop) constexpr int sz = sizeof(ImageBlock); // 此时sz会是10
这样结构体回到POD类型,#pragma pack(1)的设置就能正常生效,Header的大小是6字节,ImageBlock总大小为6+4=10字节,符合1字节对齐的预期。
内容的提问来源于stack exchange,提问作者Valerii Chistyakov
相关产品推荐
相关产品推荐

