1. 编译器通常会使结构体强制对齐.
这里默认使用VC编译器,默认8bytes 对齐的,
对于结构体
struct struct_x {
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
} ;
编译器会自动插入一些pad
struct struct_x {
char a; // 1 byte
char _pad0[3]; // padding to put 'b' on 4-byte boundary
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
char _pad1[1]; // padding to make sizeof(x_) multiple of 4
}
所以sizeof(struct_x) 的返回值会是 12 bytes.
char _pad0[3] 使 int b 成员 4字节对齐;
(这里如果是double b;的话,因为double类型长是8字节的,所以变量b会被编译器强制8 bytes对齐
这样就需要插入char_pad0[7] 了);
char _pad1[1] 使结构体每个成员都对齐;
(试想一下,如果这个字节不插入, 则定义类似结构体数组 strcut my_struct x[3] 的时候,x[1]就无法对齐了.)
2. 对于嵌套定义结构体的话,编译器会按嵌套的数据成员对齐长度对齐.
对于结构体
struct struct_x
{
char xa; // 1 byte
int xb; // 4 bytes
}
sizeof(struct_x) 的返回值会是 8 Bytes. 数据成员按4 Bytes 对齐
struct struct_y
{
char ya; // 1 byte
struct struct_x yb // 8 bytes
int yc; // 4 bytes
double yd; // 8 bytes
char ye; // 1 byte
} ;
struct_y 会不会被编译器对齐成这样呢?
struct struct_y
{
char ya; // 1 byte
char _pad0[7];
struct struct_x yb // 8 bytes
int yc; // 4 bytes
char _pad1[4];
double yd; // 8 bytes
char ye; // 1 byte
char _pad2[7];
} ;
因此sizeof(struct_y) 的返回值是 40 bytes ?
答案是否定的,编译器会优化成
struct struct_y
{
char ya; // 1 byte
char _pad0[3]; // padding to put 'yb' on 4-byte boundary
struct struct_x {
char xa; // 1 byte
char _pad1[3]; // padding to put 'xa' on 4-byte boundary
int xb; // 4 bytes
} yb;
int yc; // 4 bytes
double yd; // 8 bytes // Here yd is alreay 8-byte boundary,so no need to pad.
char ye; // 1 byte
char _pad1[7]; // padding to make sizeof(x_) multiple of 8
} ;
因此sizeof(struct_y) 的返回值是 32 bytes!!
3. 结构体packet 化.
VC编译器可以通过 #pragma pack(x) 使结构体packet 化
GCC编译器则可以通过 __attribute__(packet) 或 __attribute__(align(x)) 使结构体packet 化
struct_x强制 模1 对齐.
# pragma pack (1)
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} ;
# pragma pack ()
或
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
}__attribute__(packet) ;
sizeof(struct_x) 的返回值会是 7 bytes!!
struct_x被强制 模2 对齐.
# pragma pack (2)
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} ;
# pragma pack ()
或
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
}__attribute__(align(2)) ;
相当于
struct struct_x
{
char a; // 1 byte
char _pad0[1]; // padding to put 'b' on 2-byte boundary
int b; // 4 bytes // b 被强制 模2 对齐了
short c; // 2 bytes
} ;
因此 sizeof(struct_x) 的返回值会是 8 bytes!!
struct_x被强制 模8 对齐.
# pragma pack (8)
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} ;
# pragma pack ()
或
struct struct_x
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
}__attribute__(align(8)) ;
相当于
struct struct_x
{
char a; // 1 byte
char _pad0[3]; // padding to put 'b' on 4-byte boundary ,.
int b; // 4 bytes , int 类型 模8 ,b 还是按4 bytes 对齐
short c; // 2 bytes
} ;
因此 sizeof(struct_x) 的返回值会是 12 bytes!!