Sayeth the C standard, regarding anonymous structs and unions:
6.7.2.1 p13. An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.
Note emphasis: rather than the members of the anonymous struct/union being in the scope of the containing struct/union, they are fully members of it. But there are responsibilities attached to that:
6.7.2.1 p16. The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.
Taken together, those seem to imply that the members of an anonymous struct within a (named) union behave like co-located, mutually-exclusive members of the union. So the following should work:
union Foo
{
struct
{
char a;
char b;
};
};
int main(void) {
union Foo f;
assert(&f == &(f.a) && &f == &(f.b));
}
Of course, it doesn't, and we wouldn't want it to... there'd be no reason for anonymous structs/unions if they worked like the above. Still, the Standard seems unambiguous on that point. Is there something I'm missing?
An anonymous union is a union without a name. It cannot be followed by a declarator. An anonymous union is not a type; it defines an unnamed object. The member names of an anonymous union must be distinct from other names within the scope in which the union is declared.
A structure can be nested inside a union and it is called union of structures. It is possible to create a union inside a structure.
Anonymous unions/structures are also known as unnamed unions/structures as they don't have names. Since there is no names, direct objects(or variables) of them are not created and we use them in nested structure or unions. Definition is just like that of a normal union just without a name or tag.
Each data object in a structure is a member or field. A union is an object similar to a structure except that all of its members start at the same location in memory. A union variable can represent the value of only one of its members at a time.
This looks like a wording issue, they should not overlap.
This is covered in Defect Report (DR) 499 which asks:
Given the following code:
union U { struct { char B1; char B2; char B3; char B4; }; int word; } u;
Does the storage of B1, B2, B3 and B4 overlap?
According to 6.7.2.1#13, the members should overlap in storage as they become members of 'union U'.
At least one implementation (GCC) seems to NOT consider them to be overlapping.
At least one implementation (IBM's XL LE AIX) considers them to be overlapping as the standard currently states.
And the committees response was:
The storage does not overlap.
A related issue is to be found in DR 502 and both may be resolved with coordinated wording changes.
and (emphasis added)
Change §6.7.2.1 p13 from:
An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.
to:
An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type with no tag is called an anonymous union. The names of members of an anonymous structure or union are added to the name space of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.
would adequately resolve the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With