__attribute__((packed))与#pragma pack(push,1)结构体大小不一致问题
x64架构下两种紧凑打包方式的结构体大小差异
环境信息
- 架构:x64
- 操作系统:Linux、VxWorks
- 编译器:
- Linux平台:gcc-12
- VxWorks平台:Clang 16
测试代码
#include <cstdint> #include <iostream> typedef struct { std::uint8_t num1; std::uint16_t num2; std::uint32_t num3; float num4; }transmit1_t __attribute__((packed)); #pragma pack(push, 1) typedef struct { std::uint8_t num1; std::uint16_t num2; std::uint32_t num3; float num4; }transmit_t; #pragma pack(pop) int main(int argc, char const *argv[]) { std::cout << "transmit_t size : " << sizeof(transmit_t) << std::endl; std::cout << "transmit1_t size : " << sizeof(transmit1_t) << std::endl; return 0; }
输出结果
transmit_t size : 11 transmit1_t size : 12
差异原因
两者的核心区别在于结构体的尾部填充规则:
#pragma pack(push,1):将全局对齐边界设为1,既移除成员间的填充字节,也把结构体的整体对齐要求降低为1字节,因此不会在结构体末尾添加填充,总大小为1+2+4+4=11。__attribute__((packed)):仅移除成员间的填充,但结构体的整体对齐仍遵循内部最严格成员的对齐要求——x64架构下float类型要求4字节对齐,编译器会在结构体末尾添加1字节填充,让总大小凑到4的倍数(12),以满足整体对齐需求。
内容的提问来源于stack exchange,提问作者Dark Sorrow
相关产品推荐
相关产品推荐

