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 fieldsc
andd
, 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 betweenc
andd
, also resulting insizeof == 12
.
Is there a generic way to obtain the layout of PACK4
, but without using pragmas?