In C11 standard there is following definition of common initial sequence shared by structures nested within a single union:
6.5.2.3/6
One special guarantee is made in order to simplify the use of unions:
if a union contains several structures that share a common initial
sequence (see below), and if the union object currently contains one
of these structures, it is permitted to inspect the common initial
part of any of them anywhere that a declaration of the completed type
of the union is visible. Two structures share a common initial
sequence if corresponding members have compatible types (and, for
bit-fields, the same widths) for a sequence of one or more initial
members.EXAMPLE 3 The following is a valid fragment:
union { struct { int alltypes; } n; struct { int type; int intnode; } ni; struct { int type; double doublenode; } nf; } u; u.nf.type = 1; u.nf.doublenode = 3.14; /* ... */ if (u.n.alltypes == 1) if (sin(u.nf.doublenode) == 0.0) /* ... */
According to my understanding of this article, the above code, however, is invalid.
In the outer if statement we indicate that n::alltypes data member is active (simultaneously with ni::type and nf::type as the standard states) yet in the inner if we use nf::doublenode which is not a part of the common initial sequence.
Can somebody clarify this issue?
Using the provided example, this part of the specification is saying that since each possible member type of the
unionhas anintas the initial field, you can access that common initial field using any of the member types, even after the variable has been initialized/used as one of the specific member types.This is just what the example does: it accesses the initial
intas thealltypesmember of ann, after having initialized following fields as annf, and then goes on to access thedoublenodefield of annf, all using the same variable.Using the
unionas one of the possible types doesn’t force it into some sort of structure: this is how unions work.Note that this guarantee has been around for some time: essentially the same text is found in the ANSI specification, section: 3.3.2.3 Structure and union members.