Animesh Kumar Paul
Animesh Kumar Paul

Reputation: 2304

Structure Packing using __attribute__((__packed__)) in GNU GCC

We know that _attribute__((__packed__)) means (most probably) "do not insert any padding to make things faster" and may also mean "do not insert any alignments to preserve alignment".

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

Why are all padding not removed(output = 14) ?

Upvotes: 4

Views: 14766

Answers (2)

dragosht
dragosht

Reputation: 3275

Looks like a bug to me ...

By using your compiler ((tdm64-1) 4.7.1) and the appropriate packed attribute I'm getting the same behavior - see the main disassembly below:

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
  ...

Using gcc (GCC) 4.9.3 in cygwin I get:

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
   ...

So, for some reason the compiler you're using seems the ignore the attribute. You may want to try a newer one, though - the newest version of this TDM-GCC seems to be 5.1.0.

Upvotes: 2

Kerrek SB
Kerrek SB

Reputation: 477522

Try:

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

It doesn't make sense to pack one single field. As you said it yourself, padding is about the relationship between fields, so the attribute belongs on the struct itself, not on its fields.

Upvotes: 13

Related Questions