编译器会尽量把成员对齐以提高内存的命中率。对齐是可以更改的,使用"#pragma pack(x)“ 可以改变编译器的对齐方式。 C++固有类型的对界取编译器对齐方式与自身大小中较小的一个。例如,指定编译器按2对齐,int 类型的大小是4,则int 的对界为2和4中较小的2。在默认的对界方式下,几乎所有的数据类型都不大于默认的对界方式4,因此所有的固有类型的对齐方式可以认为就是类型自身的大小。
示例程序如下:
#include <iostream> using namespace std; #pragma pack(2) union u { char buf[9]; int a; }; int main() { cout << sizeof(u) << endl; return 0; }
上面的程序中,由于使用手动更改对齐方式为2,所以int 的对齐也变成了2 (int 自身对齐为4),u的对齐取成员中最大的对齐,也是2,所以此时sizeof(u) = 10 。
如果注释上面的代码第三行,int 的对齐使用4,取成员中最大的对齐,也是4,所以此时sizeof(u) = 12 。
#include <iostream> using namespace std; #pragma pack(1) struct test { char c; short s1; short s2; int i; double a; }; int main() { cout << sizeof(test) << endl; return 0; }
代码第三行用"#pragma pack" 将对齐设为1。由于结构体test中的成员s1、s2、i和a自身对齐分别为2、2、4和8,都大于1.因此它们都是用1作为对齐,sizeof(test) = 1+2+2+4+8 = 17 。
如果注释代码第三行,则使用它们自身的对齐且小于等于默认对齐4,sizeof(test) = 1+1(对齐) +2+2+2(对齐)+4+8 = 20.