Walter said:
The wording in C89 about unions indicates that padding is allowed
only at the end of the union: each member of the union is
required to start at the common address.
But this wording doesn't rule out internal padding in the union members.
Consider (assuming sizeof(short)==2 and sizeof(int)==4 for the sake of
discussion):
struct s {
short m1; /* p1==2 */
int m2;
}; /* sizeof(s)==8 ? */
union u {
struct s n1;
int n2; /* p2==4 */
short n3; /* p3==6 */
}; /* sizeof(u)==8 ? */
If for instance alignment requirements are such that each primitive type
must be aligned on a multiple of its size, then I would expect that the
above struct s had an internal padding at "p1" (of 2 bytes as
indicated). Variables of type "struct s" or "union u" would both be
aligned at 4-byte boundaries (its most restrictive member).
So even though the union u still has only padding at its end (of
different sizes, marked as "p2" and "p3" above), then it still contains
an "inherited" internal padding from its n1 member. It would, in fact,
be highly unexpected that it lost this internal padding as soon as it
became the member n1 in union u!
In other words, I would expect that
n2 occupies the storage of m1+p1,
n3 is the same storage as m1,
m2 is the same storage as p2.
And further, assuming that a "#pragma pack(1)" or similar that the
compiler honored was introduced later, before we defined
struct t {
struct s a;
short b;
long c;
};
then I _still_ would be surprised if not the internal padding of struct
s is still present in the member a, even though I would of course not
expect any padding between the other members b and c.
-+-Ben-+-