This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Accepted as a DR at the November, 2022 meeting.]
Consider:
struct S { explicit S(int){} }; struct A { S s; }; struct B { union { S s; }; }; int main() { A a1 = {.s{0}}; // #1 A a2{.s{0}}; // #2 B b1 = {.s{0}}; // #3 B b2{.s{0}}; // #4 }
Subclause 9.4.2 [dcl.init.aggr] bullet 4.2 specifies:
Otherwise, the element is copy-initialized from the corresponding initializer-clause or is initialized with the brace-or-equal-initializer of the corresponding designated-initializer-clause.
It is unclear what kind of initialization is performed for "is initialized". For example, one could imagine that the top-level kind of initialization is inherited. On the other hand, 9.4.1 [dcl.init.general] paragraph 14 specifies:
The initialization that occurs in the = form of a brace-or-equal-initializer or condition (8.5 [stmt.select]), as well as in argument passing, function return, throwing an exception (14.2 [except.throw]), handling an exception (14.4 [except.handle]), and aggregate member initialization (9.4.2 [dcl.init.aggr]), is called copy-initialization.
There is implementation divergence: gcc and icc reject the example; clang and MSVC accept.
Suggested resolution [SUPERSEDED]:
Change in 9.4.2 [dcl.init.aggr] bullet 4.1 as follows:
If the element is an anonymous union member and the initializer list is a brace-enclosed designated-initializer-list, the element is initialized by thedesignated-initializer-listbraced-init-list { D }, where D is the designated-initializer-clause naming a member of the anonymous union member.
Change in 9.4.2 [dcl.init.aggr] bullet 4.2 as follows:
Otherwise, the element is copy-initialized from the corresponding initializer-clause or isinitializedcopy-initialized or direct-initialized with the brace-or-equal-initializer of the corresponding designated-initializer-clause, according to the form of the brace-or-equal-initializer (9.4.1 [dcl.init.general]). ...
CWG telecon 2022-09-09:
The examples #1 to #4 should all be valid, direct-initializing the s member.
Proposed resolution (approved by CWG 2022-09-23):
Change in 9.4.1 [dcl.init.general] paragraph 14 as follows:
The initialization that occurs in the = form of a brace-or-equal-initializer or condition (8.5 [stmt.select]), as well as in argument passing, function return, throwing an exception (14.2 [except.throw]), handling an exception (14.4 [except.handle]), and aggregate member initialization other than by a designated-initializer-clause (9.4.2 [dcl.init.aggr]), is called copy-initialization.
Change in 9.4.2 [dcl.init.aggr] bullet 4.1 as follows:
If the element is an anonymous union member and the initializer list is a brace-enclosed designated-initializer-list, the element is initialized by thedesignated-initializer-listbraced-init-list { D }, where D is the designated-initializer-clause naming a member of the anonymous union member.
Change in 9.4.2 [dcl.init.aggr] bullet 4.2 as follows:
Otherwise, the element is copy-initialized from the corresponding initializer-clause or is initialized with the brace-or-equal-initializer of the corresponding designated-initializer-clause. If that initializer is of the form assignment-expression or = assignment-expression and a narrowing conversion (9.4.5 [dcl.init.list]) is required to convert the expression, the program is ill-formed. [ Note: If the initialization is by designated-initializer-clause, its form determines whether copy-initialization or direct-initialization is performed.-- end note]