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 fieldscandd, but at the end of the struct, to ensure it is a multiple of 4 (hencesizeof == 12);#pragma pack(4)leaves a 3-byte gap betweencandd, also resulting insizeof == 12.
Is there a generic way to obtain the layout of PACK4, but without using pragmas?