DSP

结构体字节对齐pragma pack, __attribute__(packed)

2019-07-13 18:33发布

一、pragma pack 1、 #pragma pack(push): 英文单词push是“压入”的意思。编译器编译到此处时将保存对齐状态(保存的是push指令之前的对齐状态)。 #pragma pack(pop): 英文单词pop是”弹出“的意思。编译器编译到此处时将恢复push指令前保存的对齐状态(请在使用该预处理命令之前使用#pragma pack(push))。 push和pop是一对应该同时出现的名词,只有pop没有push不起作用,只有push没有pop可以保持之前对齐状态(但是这样就没有使用push的必要了)。 例1: #include #pragma pack(2) #pragma pack(push) #pragma pack(4) struct CC { double d; char b; int a; short c; }; #pragma pack(1) struct BB{ double d; char b; int a; short c; }; #pragma pack(pop) struct AA{ double d; char b; int a; short c; }; int main(void) { printf("%u %u %u ",sizeof(struct CC),sizeof(struct BB),sizeof(struct AA)); return 0; } 执行结果: aa:20 bb 15 cc:16 2、4个字节对齐 方法一: 默认 pragma   pack(4) sturt{ }4个字节对齐 pragma   pack() 恢复默认 方法二: #pragma pack(push)  #pragma pack(4) struct{ } #pragma pack(pop)  注意   #pragma pack() 取消自定义对齐方式,恢复默认方式,而push之后pop是回到push指令之前的对齐方式。 例2: #include #pragma pack(2) #pragma pack(push) #pragma pack(4) struct CC { double d; char b; int a; short c; }; #pragma pack(1) struct BB{ double d; char b; int a; short c; }; #pragma pack() struct AA{ double d; char b; int a; short c; }; int main(void) { printf("%u %u %u ",sizeof(struct CC),sizeof(struct BB),sizeof(struct AA)); return 0; } 执行结果: aa:20 bb 15 cc:24 3、 #pragma pack(push) #pragma pack(4) #pragma pack(pop) 等价于 #pragma pack(push,4) #pragma pack(pop) 语法:
#pragma pack( [show] | [push | pop] [, identifier], n ) 说明:
1,pack提供数据声明级别的控制,对定义不起作用;
2,调用pack时不指定参数,n将被设成默认值;
3,一旦改变数据类型的alignment,直接效果就是占用memory的减少,但是performance会下降; 二、__attribute((packed)) __attribute(aligned(n)) 让所作用的数据成员对齐在n字节的自然边界上;如果结构中有成员的长度大于n,则按照最大成员的长度来对齐; __attribute((packed)) 取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐