How can I define #pragma pack(2)
as a structure attribute?
I've read here that __attribute__((packed,aligned(4)))
is roughly equivalent to #pragma pack(4)
.
However, if I try to use this (at least with 2 instead of 4), I get different results. Example:
#include <stdio.h>
#pragma pack(push, 2)
struct test1 {
char a;
int b;
short c;
short d;
};
struct test1 t1;
#pragma pack(pop)
struct test2 {
char a;
int b;
short c;
short d;
} __attribute__((packed,aligned(2)));
struct test2 t2;
#define test(s,m) printf(#s"::"#m" @ 0x%04x\n", (unsigned int ((char*)&(s.m) - (char*)&(s)))
#define structtest(s) printf("sizeof("#s")=%lu\n", (unsigned long)(sizeof(s)))
int main(int argc, char **argv) {
structtest(t1);
test(t1,a);
test(t1,b);
test(t1,c);
test(t1,d);
structtest(t2);
test(t2,a);
test(t2,b);
test(t2,c);
test(t2,d);
}
Output is (compilation on x86 or x86x64, Linux, gcc 4.8.4):
sizeof(t1)=10
t1::a @ 0x0000
t1::b @ 0x0002
t1::c @ 0x0006
t1::d @ 0x0008
sizeof(t2)=10
t2::a @ 0x0000
t2::b @ 0x0001
t2::c @ 0x0005
t2::d @ 0x0007
The adresses of members b, c and d are not the same in both cases.
Is there another __attribute__
I have to add? I can't even find a fine granular documentation on these attributes in the gcc documentation.
offsetof
macro? – Euphratessize_t
(which whatsizeof
gives you) is"z"
. So if you want to print asize_t
you should be using e.g."%zu"
. – Euphratesoffsetof
and the format for asize_t
is%zu
since C99. – Lyonnesseoffsetof
and%zu
are not supported by Visual Studio 8 (on which my code has to compile :-( ) – Sasin#pragma pack(2)
does), add__attribute__((__aligned__ (2)))
to each member of the structure --char a __attribute__((__aligned__ (2)));
and so on --, and keep the__attribute__((__packed__, __aligned__ (2)))
for the entire structure. – Endurable