编译器与字节对齐

来源:互联网 发布:js两个数组比较去重 编辑:程序博客网 时间:2024/05/16 18:52

编译器版本
gcc 4.1.2
VC 6.0

上次研究了结构体和字节对齐的问题,不过有个复合结构体有点奇怪。
#pragma pack(8)
struct S1
{
short a; // 2 byte
long b; // 4 byte
};

struct S2
{
char c; //1 byte
struct S1 d; //8 byte
long long int e; //8 byte, VC 6.0下可用double型代替此类型
};
#pragma pack()

在gcc下, sizeof(struct S2) = 20, 但在VC 6.0下却是24!

其实,这个牵扯到了编译器自身的默认对齐大小。gcc默认是按4字节对齐的,VC 6.0默认是按8字节对齐。但我们可以在程序中加入预编译指令改变默认对齐大小。

#pragma pack(n)
...
#pragma pack()

经过测试, 在gcc和VC 6.0中,当分别指定n值为1,2,4时,struct S2的大小相同,分别为15, 16, 20。n=1时, 空间最省,但存取效率低了。但n=8时,gcc 计算的结果为20, VC 6.0计算的结果为24. 貌似使用#pragma pack(8)对gcc不起作用,还是按默认的4字节对齐。在gcc官方网站上

(http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Structure_002dPacking-Pragmas.html#Structure_002dPacking-Pragmas), 可看到gcc是为了与Win32保持兼容性才引入pragma预编译指令的。不过,如果非要指定gcc按8字节对齐也是有办法的,可以使用__attribute__ ((aligned(8)))

struct S1
{
short a;
long b;
};

struct S2
{
char c;
struct S1 d;
long long int e;
} __attribute__ ((aligned(8)));

这样,再计算sizeof(struct S2)时,就是24了。

0 0