cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[dcl.init.list] Avoid zero-sized backing array #413

Closed frederick-vs-ja closed 12 months ago

frederick-vs-ja commented 12 months ago

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [dcl.init.list]

Link to reflector thread (if any):

Issue description:

The current wording in [dcl.init.list] p5 seemingly talks about a backing array of zero size when the initializer list is empty, while "array of 0 const E" is not a valid type.

It is probably fine to make std::initializer_list<E> follow the usual rule of list-initialization of objects other types (i.e. just using the default constructor) when the initializer list is empty.

Suggested resolution:

Change [dcl.init.list] p3.6 as indicated:

Otherwise, if T is a specialization of std​::​initializer_list<E> and the initializer list is not empty, the object is constructed as described below.

Change [dcl.init.list] p5 as indicated:

An object of type std​::​initializer_list<E> is constructed from ~an~ a nonempty initializer list as if the implementation generated and materialized ([conv.rval]) a prvalue of type “array of N const E”, [...]

RealLitb commented 12 months ago

This was already reported once as an issue but was deemed not a defect, because C++ does have zero sized arrays (places where the spec says otherwise are all comments/footnotes or talk about array declarators). The mechanism by which the backing array is created is not specified .

Also as I pointed out in the other issue report (clarity for "new T[0]"), the case where the array is empty is not hit for the initializer_list, because using "{}" value-initializes initializer_list and will not create the backing array as far as I can tell.

jensmaurer commented 12 months ago

According to [initializer.list.syn], an initializer_list has a default constructor. Thus, [dcl.init.list] p3.5 is satisfied and we never get to p3.6.