If I have a struct like this:
struct S {
ANY_TYPE a;
ANY_TYPE b;
ANY_TYPE c;
} s;
Can I safely assume that the following assump
In C++ you can be certain that these assumptions will hold. In struct like this, the compiler is not allowed to change the order of the members.
This is true for a struct, but changes in C++ as soon as you introduce access specifiers. The compiler is allowed to reorder whole blocks delimited by access specifiers.
Yes, in C at least. The compiler is free to insert padding after any structure member but it must not reorder the members.
It must also not insert padding before the first member.
From C99, 6.7.2.1
:
13/ Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
15/ There may be unnamed padding at the end of a structure or union.
Yes, by default C++ compilers aren't allowed to move around elements in a struct which makes both statements trivially true.
This changes in C++20 (at least the current draft): if you annotate a
, b
, and c
with [[no_unique_address]]
and they happen to be empty structures it's possible that they will all have the same address.
In fact it's more complex - if any two are empty and annotated with that then all 3 can share an address.
Yes (as long as sizeof(ANY_TYPE) is not 0. Some compilers allow it, which is non-standard -- see Can sizeof return 0 (zero)). You'd be safe with <= or just assume a standard compiler.
Yes
And in C++ too.
Pointer comparison only makes sense inside of arrays and structs/classes, not generally.