C++0x, exact semantics of initializer_list<E>

In a Google tech talk, Bjarne Stroustrup answered an audience question
about whether it is possible to return std::initializer_list objects
from functions with "Yes.". However, after having read the relevant
sections of the recent draft (N3090.pdf)...

section 8.5.4 ("List initialization"):

4 An object of type std::initializer_list<E> is constructed from an
initializer list as if the implementation allocated an array of N
elelemts of type E, where N is the number of elements in the
initializer list. Each element of that array is copy-initialized
with the corresponding element of the initializer list, and the
std::initializer_list<E> object is constructed to refer to that
array. [...] [Example:

struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };

The initialization will be implemented in a way roughly equivalent
to this:

For v1 and v2, the initializer_list object and array created for
{ 1, 2, 3 } have full-expression lifetime. For i3, the
initializer_list object and array have automatic lifetime.
-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 ]

section 18.9 ("Initializer lists")

2 [...] Copying an initializer list does not copy the underlying
elements.

....I have trouble figuring out whether Stroustrup was right or wrong.
The standard doesn't require the compiler to store the array
statically initialized in a read-only section. So, in the worst case
the array has automatic storage and the array will be destroyed before
the function returns (see implementation example from 8.5.4/4).

Advertisements

On 22 Jul., 18:33, Alf P. Steinbach wrote:
>
> I'm guessing the answer is the same as for returning a pointer
> or reference.
>
> After all an initializer_list seems to be no more than two
> pointers.

Judjung by the examples and comments, yes. And I guess that anything
more complicated (array on stack OR heap with ref-counting) is not
what the designers had in mind.
> E.g. you might return an initializer list constructed from
> a static array

As far as I can tell initializer_list objects are only created via the
list initialization syntax. In cases like {1,2,3} it should be easy
for the compiler to create a static array (much like string literals)
but this behaviour is not guaranteed, so, it doesn't seem to work
reliably.

* SG, on 22.07.2010 19:14:
> On 22 Jul., 18:33, Alf P. Steinbach wrote:
>>
>> I'm guessing the answer is the same as for returning a pointer
>> or reference.
>>
>> After all an initializer_list seems to be no more than two
>> pointers.
>
> Judjung by the examples and comments, yes. And I guess that anything
> more complicated (array on stack OR heap with ref-counting) is not
> what the designers had in mind.
>
>> E.g. you might return an initializer list constructed from
>> a static array
>
> As far as I can tell initializer_list objects are only created via the
> list initialization syntax. In cases like {1,2,3} it should be easy
> for the compiler to create a static array (much like string literals)
> but this behaviour is not guaranteed, so, it doesn't seem to work
> reliably.

Well, I read up on it.

Initialization of an object O with initializer_list argument constructor, from a
brace initializer, works /as if/ (my words) an array A is created with same
lifetime as the initializer_list formal constructor argument, that array A is
initialized from the brace initializer, and the initializer_list object is set
to point to begin and end of that array A.

Since initializer_list objects are copyable initializer_list has a copy
constructor, hence an initializer_list object can be initialized from a brace
initializer, hence, what about just a 'static std::initializer_list<T> O = ..."?

However, then we're into non-normative example territory.

For formally the initializer_list object that governs the lifetime of the array
would be the copy constructor's object, which doesn't exist very long, so the
array A would only have full-expression lifetime. However, the non-normative
example in §8.5.4/5 makes the claim that when the object O that is initialized
by a brace expression is itself of type initializer_list, then the array has the
same lifetime as O (and not just as its copy constructor formal argument).

Anyway, this seems to work with g++ 4.4.1, while MSVC 10.0 chokes on its own
<initializer_list> header.

That post includes a comment from Stephen T Lavavej (owner of STL at
Microsoft) at the very end. He says:
> btw, will the initializer list be implemented in visual studio soon ?
Magic 8 Ball says: "Ask again later."
(I really want initializer lists, but they're actually not in my top
three list of desired features. Also, please ignore the
<initializer_list> header that I accidentally left in VC10 RTM. It
doesn't do anything.)

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!