一、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))
取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐