1

To be able to perform some systematic code transformations, I'd like to get rid of #pragma pack directives in my code, and replace them with local attributes, e.g. packed, aligned(n).

However, the behavior I get is not exactly the same: while sizeof works, offsetof gives a different result. Here's an example:

#include <stddef.h>
#include <stdio.h>
#include <stddef.h>

struct WITH_ATTRS {
  char c;
  double d;
} __attribute__((packed,aligned(4)));

#pragma pack(4)
struct PACK4 {
  char c;
  double d;
};

int main() {
  printf("sizeof(WITH_ATTRS) = %zu\n", sizeof(struct WITH_ATTRS));
  printf("offsetof(WITH_ATTRS, d) = %zu\n", offsetof(struct WITH_ATTRS, d));

  printf("sizeof(PACK4) = %zu\n", sizeof(struct PACK4));
  printf("offsetof(PACK4, d) = %zu\n", offsetof(struct PACK4, d));
  return 0;
}

GCC (5.4.0) and Clang (3.8.0) both output the same thing for me:

sizeof(WITH_ATTRS) = 12
offsetof(WITH_ATTRS, d) = 1
sizeof(PACK4) = 12
offsetof(PACK4, d) = 4

So, what I understand from this is that:

  • __attribute__((packed,aligned(4))) leaves no gap between fields c and d, but at the end of the struct, to ensure it is a multiple of 4 (hence sizeof == 12);
  • #pragma pack(4) leaves a 3-byte gap between c and d, also resulting in sizeof == 12.

Is there a generic way to obtain the layout of PACK4, but without using pragmas?

anol
  • 8,264
  • 3
  • 34
  • 78
  • The data can be either packed or aligned. Specifying both attributes doesn't make sense for me. Your results suggest that the seconds attribute `aligned(4)` is ignored. – harper Sep 09 '16 at 09:23
  • This question is indeed related to http://stackoverflow.com/questions/14179748/, but the solution presented there is not complete: without a `packed` attribute, in my example the layout of the structs will not be the same. My question is more oriented as a reference of what needs to be done in practice, but perhaps editing the other question would suffice. – anol Sep 09 '16 at 09:32
  • @harper from what I understand, the `pragma pack` directive does have this behavior of both specifying packing *and* a minimum alignment, hence the need for both attributes. – anol Sep 09 '16 at 09:37
  • Going over this a year later -- the comments can be misleading -- the `aligned(4)` applies to the structure, not its members -- the start of the structure has to be aligned to 4 bytes, BUT the `aligned` does not apply to the members of the structure, therefore the members can start where they want (and because of the `packed` attribute, the second member starts at offset 1). – HardcoreHenry Dec 07 '17 at 16:20

0 Answers0