Can we count on C structs well behaved format?
Can we predict how a C struct will be implemented by the compiler?
If I write the (very badly aligned) struct:
struct {
uint16_t a;
uint32_t b;
uint8_t c;
} s;
char *p = (char*)&s;
can I guarantee that p[6]
is the same as s.c
? Are the struct fields allocated in this most obvious and canonical way, so we can predict where each field will be in memory?
Edit: Will struct __attribute__ ((__packed__)) {...} s;
get me this behavior in G开发者_开发技巧CC?
No you cannot. Don't do that.
You are guaranteed only the order and the same compiler will always do the same layout.
If you need such a thing consult your compiler's documentation for how to enable byte packing (always available) and pad yourself.
The fields have to be allocated in ascending order, but the compiler is free to insert padding between fields as it sees fit, so there's no guarantee of what value of n
in p[n]
will refer to s.c
. OTOH, you can obtain the correct offset using offsetof(s,c)
.
Even with the __packed__
attribute, it may be impossible to get this alignment due to architectural restrictions. For example, if uint32_t
requires 4-byte alignment, it will be at offset 4 even with __packed__
.
If you need to assume a particular alignment, put in a static check that will prevent the code compiling with a different alignment.
For a given version of a compiler on a given version of the operating system - and with the same build options = yes
But don't !
See #pragma pack(packed)
and #pragma pack(reset)
. It has the same impact as the GCC attribute __packed__
you mentioned.
精彩评论