This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


2619. Kind of initialization for a designated-initializer-list

Section: 9.4.2  [dcl.init.aggr]     Status: C++23     Submitter: Jim X     Date: 2022-07-13

[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]:

  1. 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 the designated-initializer-list braced-init-list { D }, where D is the designated-initializer-clause naming a member of the anonymous union member.
  2. 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 copy-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):

  1. 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.
  2. 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 the designated-initializer-list braced-init-list { D }, where D is the designated-initializer-clause naming a member of the anonymous union member.
  3. 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]