pragma pack打包数据结构

Packing data structures(编译器入门 Gulde:打包数据结构)

通过将数据打包到结构中,可以减少应用程序所需的内存量。如果您需要在嵌入式系统中存储和访问大型数据阵列,这一点尤为重要。

如果结构中的各个数据成员没有打包,编译器可以在结构中添加填充,以便根据每个成员的自然对齐方式更快地访问各个成员。Arm®编译器提供了一个杂注和属性,用于在没有任何填充的情况下将成员打包到结构或联合中。

将成员打包到结构体或联合体中

编译指示或属性

#pragma pack(n) 对于每个成员,如果n字节小于该成员的自然对齐方式,则将对齐方式设置为n字节,否则对齐方式为该成员的自然对齐方式。 有关详细信息,请参阅#pragma pack (n)__alignof__

__attribute__((packed)) 这相当于#pragma pack (1)。 但是,该属性也可以用于结构或联合中的各个成员。

要打包整个结构或联合,请使用 __attribute__((packed))#pragma pack(n) 来声明结构,

使用#pragma pack(n)时,结构的对齐方式是将#pragma pack(n)应用于结构后最大成员的对齐方式。

指定字节几个字节对其方式,n可以指定 1 2 4 8

关于#pragma pack

C/C++中用于调整结构体或类成员内存对齐方式的预处理指令;

定义 描述
#pragma pack(push, 1) **push‌: 将当前对齐规则压入编译器内部栈保存,以便后续恢复
1**‌: 设置新的内存对齐字节数为1,即强制所有成员按1字节对齐(取消默认对齐填充)
将当前对齐状态压栈后设置新对齐值,通过 pop 可自动恢复原始设置,避免污染全局对齐规则
参考示例一:
#pragma pack(pop)
#pragma pack(1) 直接设置对齐为1字节,但不会保存当前对齐状态,需手动恢复(如 #pragma pack()
#pragma pack(2)
#pragma pack(4)

示例一:

1
2
3
4
5
6
#pragma pack(push, 1)  // 保存当前对齐规则并设为1字节对齐  
struct Example {
char a;
int b; // 成员b紧接a存储,无填充字节
};
#pragma pack(pop) // 恢复之前的对齐规则

典型使用场景

跨平台数据交互

需确保结构体内存布局在不同平台或协议中严格一致(如网络传输、文件读写)

内存优化

  • 减少结构体因默认对齐(如4/8字节)产生的填充字节,节省内存空间;
  • 编译器默认对齐可能导致 sizeof(struct) 大于成员尺寸总和。

注意事项

  • 恢复机制‌:#pragma pack(push, n) 需与 #pragma pack(pop) 成对使用,否则可能导致后续代码对齐规则混乱24;
  • 嵌套支持‌:编译器维护对齐规则的栈,允许嵌套使用多个 pushpop
  • 兼容性‌:部分嵌入式编译器可能不完全支持此指令,需测试验证