Clang is correct, GCC is wrong
As per [dcl.init.aggr]/1:
An aggregate is an array or a class ([class]) with
- (1.1) no user-declared or inherited constructors ([class.ctor]),
- (1.2) no private or protected direct non-static data members ([class.access]),
- (1.3) no virtual functions ([class.virtual]), and
- (1.4) no virtual, private, or protected base classes ([class.mi]).
A
, B
and U
are all aggregate classes, although the prior to are non-union aggregate classes, which the former does not qualify as.
As per [dcl.init.aggr]/5 [emphasis mine]:
For a non-union aggregate, each element that is not an explicitly
initialized element is initialized as follows:
- (5.1) If the element has a default member initializer ([class.mem]), the element is initialized from that initializer.
- (5.2) Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list ([dcl.init.list]).
- (5.3) Otherwise, the program is ill-formed.
If the aggregate is a union and the initializer list is empty, then
- (5.4) if any variant member has a default member initializer, that member is initialized from its default member initializer;
- (5.5) otherwise, the first member of the union (if any) is copy-initialized from an empty initializer list.
Thus
U u{};
is aggregate initialization, with the result that the first data member of the union class, namely the data member a
of type A
(which is a non-union aggregate class), is copy-initialized from an empty initializer list. As the single data member x
of the type A
has a default member initializer, then as per [dcl.init.aggr]/5.1 above, the data member x
is initialized by its default member initializer.
Thus, Clang is correct, and GCC is wrong.
GCC bug report
u
you're doing value initialization. And sinceU
is not a class type, it will lead tou
being zero initialized. – DesireeU
is a class type, it is union aggregate class. Note the normative term "non-union aggregate", e.g. used in [dcl.init.aggr]/5. Thus, this is aggregate initialization and [dcl.init.aggr]/5 applies (/5.5 forU u{};
followed by /5.1 for the first data membera
of the union). – Ningpo