8

If I have a field in my struct which is packed, why my whole structure is becoming packed?

Example:

#include <stdio.h>

struct foo {
  int a;
} __attribute__((packed));

struct bar {
  char b;
  struct foo bla;
  char a;
};

int main() {
  printf("%ld\n", sizeof(struct bar));
  return 0;
}

https://ideone.com/bjoZHB

Sizeof of bar struct is 6, but it should be 12, because it should be aligned.

Sukhanov Niсkolay
  • 1,298
  • 1
  • 12
  • 26

1 Answers1

6

it seems because __attribute__((packed)) means use the minimum memory for structure, it also means that it can ignore alignment for siding members when it is in another structure. Check following structure:

struct bar {
  char b;
  __attribute__((packed)) int bla;
  char a;
};

When you check size for this structure, it will be 6. This happens because it ignores member alignment for 2 side members(a and b here). But this structure:

struct bar {
  char b;
  __attribute__((packed)) int bla;
  char a;
  int c;
};

has size of 12, because it is aligned c on 4 bytes boundary. In your case, if you use aligned attribute too at same time, it works as you expect:

struct bar {
  char b;
  __attribute__((aligned (4), packed)) int bla;
  char a;
};

This structure size is 12.

Update:

I only found this in GCC's aligned section of attributes. I think it is related to what I mentioned here:

The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well

.Just remember that if you want to keep child structure packed but main structure aligned, you need to use 2 attributes in 2 different declarations. For example following structure has size of 12:

struct foo {
  char b;
  int a;
} __attribute__((packed));

struct bar {
  char b;
  __attribute__((aligned(4))) struct foo bla;
  char a;
};

but if you use aligned() in declaration of foo as __attribute__((aligned (4), packed)), size will be 16. This happens because foo gets aligned too, and it will not be useful in case of packing.

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • Where can I read about "means that it can ignore alignment when it is in another structure" I didn't find it in the gcc docs or anywhere. :( – Sukhanov Niсkolay Jan 02 '19 at 18:03
  • @SukhanovNiсkolay it had a "it seems" at start of sentence too. but I found 1 sentence about it in gcc manual and I add it to reply. – Afshin Jan 02 '19 at 18:05
  • Yeah, I saw the same cite, then it seems it is an ISO C requirement. :) UPDATE: Sorry, wrong cite, I saw this: "ISO C standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct" – Sukhanov Niсkolay Jan 02 '19 at 18:10