Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does __attribute__((packed)) for a field affect struct which contains this field?

Tags:

c

gcc

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.

like image 848
Sukhanov Niсkolay Avatar asked Jan 02 '19 17:01

Sukhanov Niсkolay


People also ask

What does __ Attribute__ packed )) Meaning?

__attribute__((packed)) variable attributeThe attribute specifies that a member field has the smallest possible alignment. That is, one byte for a variable field, and one bit for a bitfield, unless you specify a larger value with the aligned attribute.

What is __ packed in C?

The __packed qualifier sets the alignment of any valid type to 1. This means that: There is no padding inserted to align the packed object.

What does attribute packed do in C?

The packed variable attribute specifies that a variable or structure field has the smallest possible alignment. That is, one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.

What is Pragma pack in C?

The #pragma pack directive modifies the current alignment rule for only the members of structures whose declarations follow the directive. It does not affect the alignment of the structure directly, but by affecting the alignment of the members of the structure, it may affect the alignment of the overall structure.


1 Answers

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.

like image 147
Afshin Avatar answered Nov 14 '22 18:11

Afshin