Relevant C++ standard quotes:
[class.union]
In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time. [... A special case regarding classes with common initial sequence, which does not apply to this example because the union has no members of class type ...]
...
When the left operand of an assignment operator involves a member access expression ([expr.ref]) that nominates a union member, it may begin the lifetime of that union member, as described below.
For an expression E, define the set S(E) of subexpressions of E as follows:
If E is of the form A[B] and is interpreted as a built-in array subscripting operator, S(E) is S(A) if A is of array type, S(B) if B is of array type, and empty otherwise.
[... other cases are not relevant, because the quoted one applies ...]
In an assignment expression of the form E1 = E2 that uses either the built-in assignment operator ([expr.ass]) or a trivial assignment operator ([class.copy.assign]), for each element X of S(E1), if modification of X would have undefined behavior under [basic.life], an object of the type of X is implicitly created in the nominated storage; no initialization is performed and the beginning of its lifetime is sequenced after the value computation of the left and right operands and before the assignment.
[ Note: This ends the lifetime of the previously-active member of the union, if any ([basic.life]).
— end note
]
What this means that after the statement word.u8[6] = 2;
, only the word.u8
member is active, and all other union members are inactive. After the last statement word.u8[7] = 3;
, only word.u8[6]
and word.u8[7]
have initialised values.
The lifetime of the inactive members has ended. Here is a relevant rule regarding whether it is OK to read their value:
[basic.life]
Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. ... The program has undefined behavior if:
- the glvalue is used to access the object, or
- ...
So, yes. Accessing the inactive members would be UB (except when that access is an assignment, or in the special case involving common initial sequence of classes, as per [class.union]).