Title
Lifetime of the underlying array of an initializer_list member
Status
cd3
Section
9.4.5 [dcl.init.list]
Submitter
James Dennett

Created on 2011-04-08.00:00:00 last changed 90 months ago

Messages

Date: 2012-10-15.00:00:00

[Moved to DR at the October, 2012 meeting.]

Date: 2012-02-15.00:00:00

Proposed resolution (February, 2012):

  1. Change 9.4.5 [dcl.init.list] paragraphs 5-6 as follows:

  2. An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated an a temporary array of N elements of type E, where...

    The lifetime of the array is the same as that of the initializer_list object. 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 and array created for { 1, 2, 3 } have has full-expression lifetime. For i3, the initializer_list object is a variable, so the and array have automatic 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] [Note: The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. —end note]

  3. Change 6.7.7 [class.temporary] paragraph 5 as follows:

  4. The second context is when a reference is bound to a temporary. [Footnote: The same rules apply to initialization of an initializer_list object (9.4.5 [dcl.init.list]) with its underlying temporary array. —end footnote] The temporary to which...
Date: 2012-09-24.00:00:00

A question has arisen over expected behavior when an initializer_list is a non-static data member of a class. Initialization of an initializer_list is defined in terms of construction from an implicitly allocated array whose lifetime "is the same as that of the initializer_list object". That would mean that the array needs to live as long as the initializer_list does, which would on the face of it appear to require the array to be stored in something like a std::unique_ptr<T[]> within the same class (if the member is initialized in this manner).

It would be surprising if that was the intent, but it would make initializer_list usable in this context.

It would also be reasonable if this behaved similarly to binding temporaries to reference members (i.e., "temporary bound to a reference member in a constructor's ctor-initializer (11.9.3 [class.base.init]) persists until the constructor exits."), though this approach would probably prevent use of an initializer_list member in that context.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2013-05-03 00:00:00adminsetstatus: dr -> drwp
2012-11-03 00:00:00adminsetmessages: + msg4148
2012-11-03 00:00:00adminsetstatus: ready -> dr
2012-09-24 00:00:00adminsetmessages: + msg3872
2012-02-27 00:00:00adminsetstatus: drafting -> ready
2011-04-08 00:00:00admincreate