9

The following is a quote from Effective Modern C++ (page 55):

"Suppose that you use an empty set of braces to construct an object that supports default constructor and also supports std::initializer_list construction. What do your empty braces mean? etc. The rule is that you get default construction."

I tried this with std::array:

std::array<int, 10> arr{};

and got the warning from g++ (version 4.8.2):

warning: missing initializer for member ‘std::array<int, 10ul>::_M_elems’

which is the warning one gets when trying to construct an std::array from an empty std::initializer_list (see Why can I initialize a regular array from {}, but not a std::array for a discussion of this warning).

So, why isn't the above line of code interpreted as calling the default constructor?

Community
  • 1
  • 1
AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68
  • `std::array` has no constructor taking an `std::initializer_list`, and the initializer you have here isn't an `std::initailizer_list` either. It's referred to as a braced-init-list. I'm not sure why you're getting a warning, as using empty braces should value-initialize the nested array. – David G Jul 07 '15 at 20:30
  • @0x499602D2 see my answer to the linked question, gcc was being aggressive and later versions of gcc do not produce the warning. – Shafik Yaghmour Jul 07 '15 at 20:34
  • Also note that they changed the C++11 standard in a significant way in a DR. The actual standard says one thing, but compilers are expected to do something completely different. – o11c Jul 08 '15 at 00:08
  • @o11c which DR are you referring to? It is not clear to me which behavior you are referring to. – Shafik Yaghmour Jul 08 '15 at 20:20

1 Answers1

8

That is because std::array is an aggregate and therefore aggregate initialization is performed this is covered in the draft C++11 standard section 8.5.4 [dcl.init.list] which says:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).

    double ad[] = { 1, 2.0 }; // OK
    int ai[] = { 1, 2.0 }; // error: narrowing
    
    struct S2 {
      int m1;
      double m2, m3;
    };
    
    S2 s21 = { 1, 2, 3.0 }; // OK
    S2 s22 { 1.0, 2, 3 }; // error: narrowing
    S2 s23 { }; // OK: default to 0,0,0
    

and we can see if it is not an aggregate then the list goes on and says:

  • Otherwise, if T is a specialization of std::initializer_list, an initializer_list object is constructed as described below and used to initialize the object according to the rules for initialization of an object from a class of the same type (8.5).
  • Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.

We can confirm std::array is an aggregate from section 23.3.2.1 [array.overview]:

An array is an aggregate (8.5.1) that can be initialized with the syntax

array<T, N> a = { initializer-list };

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

section 8.5.1 referenced is 8.5.1 Aggregates [dcl.init.aggr] and says:

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order [...]

and we come full-circle back to section 8.5.4 which is where we started.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Could you please provide a link to the standard document that you quoted (if it is freely accessible, of course)? – AlwaysLearning Jul 07 '15 at 20:29
  • @MeirGoldenberg done added link into the answer, you can see [Where do I find the current C or C++ standard documents?](http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents) which lists all the drafts available to the public. – Shafik Yaghmour Jul 07 '15 at 20:32