众所周知,程序为了提高访问效率,编译器在编译的时候,进行字节对齐。程序员也可以字节指定对齐方式。
Win32下的为progma指令,具体来说
#pragma pack(push) // 保存原对齐状态 #pragma pack(4) // 设定为4字节对齐 struct test{ int a;}; #pragma pack(pop) // 恢复对齐状态
在linux下,gcc是默认的编译器。g++ 支持progma指令,gcc也支持GNU扩展__attribute__指令
参考,对于字节对齐的举例为
struct test{ short b[ 3 ];} __attribute__ ((aligned ( 8 )));
__attribute__还支持aligned 和 packed ,解释如下
__attribute__ ((aligned)); 选择针对目标机器最大的对齐方式,可以提高拷贝操作的效率。
aligned属性使被设置的对象占用更多的空间,相反的,使用packed可以减小对象占用的空间。
需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,
那么你此时定义32字节对齐也是无济于事的。__attribute__ ((packed))使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,
对域(field)是位对齐。
下面以pragma 来讨论指定结构体对齐方式!
总的来说规律如下
#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况: 第一、如果n大于等于该变量所占用的字节数,那么偏 移量必须满足默认的对齐方式第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条 件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
alignment (n) must be a small power of two
示例
struct test{ char m1; double m4; int m3;};
如果不指定对齐方式的话,其以double所占空间大小对齐,即
sizeof(struct test) = 24 (IA32 GCC)
此处让我想起linux中的container_of,和offset宏。