The example attempts to illustrate the paragraph beforehand1 (emphasis mine):
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.
Since f
is declared before g
, and furthermore the unnamed union type is local to g
, there is no questioning the union type isn't visible in f
.
The example doesn't show how u
is initialized, but assuming the last written to member is u.s2.m
, the function has undefined behavior because it inspects p1->m
without the common initial sequence guarantee being in effect.
Same goes the other way, if it's u.s1.m
that was last written to before the function call, than accessing p2->m
is undefined behavior.
Note that f
itself is not invalid. It's a perfectly reasonable function definition. The undefined behavior stems from passing into it &u.s1
and &u.s2
as arguments. That is what's causing undefined behavior.
1 - I'm quoting n1570, the C11 standard draft. But the specification should be the same, subject only to moving a paragraph or two up/down.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…