结构使用GNU GCC中的__attribute __((__ packed__))打包

时间:2016-01-04 09:29:48

标签: c structure padding packing

我们知道_attribute__((__packed__))意味着(最有可能)"不插入任何填充以使事情变得更快"并且也可能意味着"不要插入任何对齐以保持对齐"。

struct structure2
{
   int id1 __attribute__((__packed__));
   char name __attribute__((__packed__));
   int id2 __attribute__((__packed__));
   char c __attribute__((__packed__));
   float percentage __attribute__((__packed__));
};
struct structure2 b;
printf("   \n\nsize of structure2 in bytes : %d\n", sizeof(b));// output = 20

为什么没有删除所有填充(输出= 14)?

2 个答案:

答案 0 :(得分:9)

尝试:

struct __attribute__((__packed__)) structure2
{  //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   int id1;
   char name;
   int id2;
   char c;
   float percentage;
};

打包一个字段没有意义。正如您自己所说,填充是关于字段之间的关系,因此该属性属于结构本身,而不属于其字段。

答案 1 :(得分:2)

对我来说看起来像个错误......

通过使用您的编译器((tdm64-1)4.7.1)和相应的e = Elements[:,1:].ravel().astype(int) n=nodes[:,0].astype(int) I, J = np.where(e==n[:,None]) results = np.zeros((e.shape[0],2),nodes.dtype) results[J] = nodes[I,1:] np.concatenate((Elements[:,[0]],results.reshape(2,4)),axis=1) 属性,我得到了相同的行为 - 请参阅下面的packed反汇编:

main

在cygwin中使用0000000000401500 <main>: 401500: 55 push %rbp 401501: 48 89 e5 mov %rsp,%rbp 401504: 48 83 ec 40 sub $0x40,%rsp 401508: e8 a3 11 00 00 callq 4026b0 <__main> 40150d: ba 14 00 00 00 mov $0x14,%edx <-- your sizeof here 401512: 48 8d 0d 07 7b 00 00 lea 0x7b07(%rip),%rcx # 409020 <.rdata> 401519: e8 b2 60 00 00 callq 4075d0 <printf> 40151e: b8 00 00 00 00 mov $0x0,%eax 401523: 48 83 c4 40 add $0x40,%rsp 401527: 5d pop %rbp 401528: c3 retq ... 我得到:

gcc (GCC) 4.9.3

因此,出于某种原因,您使用的编译器似乎忽略了该属性。不过,您可能想尝试更新版本 - 此00000001004010e0 <main>: 1004010e0: 55 push %rbp 1004010e1: 48 89 e5 mov %rsp,%rbp 1004010e4: 48 83 ec 30 sub $0x30,%rsp 1004010e8: e8 33 00 00 00 callq 100401120 <__main> 1004010ed: ba 0e 00 00 00 mov $0xe,%edx <-- your sizeof here 1004010f2: 48 8d 0d 37 1f 00 00 lea 0x1f37(%rip),%rcx # 100403030 <.rdata> 1004010f9: e8 32 00 00 00 callq 100401130 <printf> 1004010fe: b8 00 00 00 00 mov $0x0,%eax 100401103: 48 83 c4 30 add $0x30,%rsp 100401107: 5d pop %rbp 100401108: c3 retq ... 的最新版本似乎是5.1.0。