Created on 2022-12-18.00:00:00 last changed 3 weeks ago
CWG 2023-01-06
CWG is soliciting the design guidance of EWG to resolve this issue:
Issue 1815 presented the following example:
struct A {}; struct B { A&& a = A{}; }; B b1; // #1 B b2{A{}}; // #2 B b3{}; // #3
CWG intended to make #3 behave like #2, i.e. the temporary created in the brace-or-equal initializer is lifetime-extended. Issue 1696 was adopted, ostensibly resolving issue 1815, but making #3 (and #1) ill-formed per 11.9.3 [class.base.init] paragraph 11:
A temporary expression bound to a reference member from a default member initializer is ill-formed. [ Example:struct A { A() = default; // OK A(int v) : v(v) { } // OK const int& v = 42; // OK }; A a1; // error: ill-formed binding of temporary to reference A a2(1); // OK, unfortunately-- end example]
However, the example does not consider aggregate initialization, and the specified resolution for issue 1696 is contrary to the stated intent in issue 1815.
There is considerable implementation variance: #1 is rejected by clang, but accepted by gcc and EDG (with early destruction of the temporary); #2 is uniformly accepted and the lifetime of the temporary is extended; #3 is uniformly accepted, but only gcc, clang, and MSVC extend the lifetime of the temporary, whereas EDG does not.
Note that 9.4.1 [dcl.init.general] paragraph 7 specifies that default-initialization of aggregates is as-if the initializer () is used:
To default-initialize an object of type T means:
- If T is a (possibly cv-qualified) class type (Clause 11 [class]), constructors are considered. The applicable constructors are enumerated (12.2.2.4 [over.match.ctor]), and the best one for the initializer () is chosen through overload resolution (12.2 [over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object.
- If T is an array type, each element is default-initialized.
- Otherwise, no initialization is performed.
Such treatment causes early destruction of temporaries per 6.7.7 [class.temporary] bullet 6.10:
The exceptions to this lifetime rule are:
- ...
- A temporary object bound to a reference element of an aggregate of class type initialized from a parenthesized expression-list (9.4 [dcl.init]) persists until the completion of the full-expression containing the expression-list.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-01-07 20:39:02 | admin | set | messages: + msg7126 |
2022-12-18 00:00:00 | admin | create |