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

2023-01-15


2150. Initializer list array lifetime

Section: 9.4.5  [dcl.init.list]     Status: CD3     Submitter: Hubert Tong     Date: 2015-06-26

The resolution of issue 1696 appears to have removed the wording that makes the initialization of A::i4 in 9.4.5 [dcl.init.list] paragraph 6 create a dangling reference:

The array has the same lifetime as any other temporary object (6.7.7 [class.temporary]), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary. [Example:

  typedef std::complex<double> cmplx;
  std::vector<cmplx> v1 = { 1, 2, 3 };

  void f() {
    std::vector<cmplx> v2{ 1, 2, 3 };
    std::initializer_list<int> i3 = { 1, 2, 3 };
  }

  struct A {
    std::initializer_list<int> i4;
    A() : i4{ 1, 2, 3 } {} // creates an A with a dangling reference
  };

For v1 and v2, the initializer_list object is a parameter in a function call, so the array created for { 1, 2, 3 } has full-expression lifetime. For i3, the initializer_list object is a variable, so the array persists for the lifetime of the variable. For i4, the initializer_list object is initialized in a constructor's ctor-initializer, so the array persists only until the constructor exits, and so any use of the elements of i4 after the constructor exits produces undefined behavior. —end example]

Binding a reference to a temporary in a mem-initializer or default member initializer is now ill-formed, per 11.9.3 [class.base.init] paragraphs 8 and 11, which undercuts the description here.

Notes from the October, 2015 meeting:

The example is incorrect and will be fixed editorially. The issue is left in "review" status to check that the editorial change has been made.