在结构体变量的声明中,经常可以看到__attribute__((packed))修饰符。这是做什么用的呢?请看一下程序:
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
int main()
{
struct {
u16 reg;
u32 test2;
u8 test1;
u8 val[256];
} msg = {
.reg = 0x8001,
.test1 = 0xff,
.test2 = 0x71727374,
.val = {0x11, 0x12, 0x13, 0x14},
};
u8* ptr = (u8*) &msg;
int i;
for (i=0; i<0x10; i++)
printf("%02x ", ptr[i]);
return 0;
}
01 80 00 00 74 73 72 71 ff 11 12 13 14 00 00 00
如果在msg前加上__attribute__((packed)) ,程序变为:
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
int main()
{
struct {
u16 reg;
u32 test2;
u8 test1;
u8 val[256];
} __attribute__((packed)) msg = {
.reg = 0x8001,
.test1 = 0xff,
.test2 = 0x71727374,
.val = {0x11, 0x12, 0x13, 0x14},
};
u8* ptr = (u8*) &msg;
int i;
for (i=0; i<0x10; i++)
printf("%02x ", ptr[i]);
return 0;
}
#define u16 unsigned short
#define u32 unsigned int
int main()
{
struct {
u16 reg;
u32 test2;
u8 test1;
u8 val[256];
} __attribute__((packed)) msg = {
.reg = 0x8001,
.test1 = 0xff,
.test2 = 0x71727374,
.val = {0x11, 0x12, 0x13, 0x14},
};
u8* ptr = (u8*) &msg;
int i;
for (i=0; i<0x10; i++)
printf("%02x ", ptr[i]);
return 0;
}
01 80 74 73 72 71 ff 11 12 13 14 00 00 00 00 00
因此可以看到,packed属性修改了编译器对结构体成员的布局,尽可能压缩存储空间。默认情况下,gcc会为了效率考量,会让char或者short独占一个双字(4字节)。
二、
_attribute_((packed))