9
struct Point {
  int x = 0;
  int y = 10;
};

Point p = {1,};
p.x == 1;  // true
p.y == 10; // is this true?

According to the standard missing elements in initializer list are value initialized, so y should be int() or 0, but it doesn't seem to say what happen in the situation of Non-static Data Member Initializer.

Edit: According to the answer, apparently this is invalid c++11, I would like to know the situation in c++1y.

5
  • I'm guessing you are talking about the new feature of C++1y? just making sure before I go in and tag the question. Commented Jun 4, 2014 at 17:21
  • 1
    Your code doesn't compile with g++4.9 (even with -std=c++14), but compiles with clang++ (only with the flag -std=c++1y). Anyway I get that p.y==10 is true Commented Jun 4, 2014 at 17:21
  • 1
    @FilipRoséen-refp: NSDMIs were introduced in C++11. Commented Jun 4, 2014 at 17:22
  • @LightnessRacesinOrbit I'm talking about the relaxation of aggregate initialization in C++14. Commented Jun 4, 2014 at 17:24
  • link is broken @FilipRoséen-refp Commented Apr 24, 2019 at 22:32

2 Answers 2

13

C++98, C++03

Non-static data member initialisers (NSDMIs) do not exist; the question is inapplicable.


C++11

Well, first of all, this initialisation is invalid because your type is not an aggregate:

[C++11: 8.5.1/1]: An aggregate is an array or a class (Clause 9) with user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

So, aggregate initialisation can't be performed here; a constructor taking an std::initializer_list would be your only way to use that initialisation syntax ([C++11: 8.5.4/3]), but you don't have one of those either.

Consequently, the entire premise of the question is flawed: it is not possible to get yourself into this state.


C++1y

In the upcoming version of the standard, the definition of aggregates has been relaxed to allow your type to be deemed an aggregate (as long as both of those members stay public!):

[n3936: 8.5.1/1] An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

Following on from this, there's a rule that guarantees the result you're looking for:

[n3936: 8.5.1/7]: If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4). [ Example:

struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", ss.c with the value of an expression of the form int{} (that is, 0), and ss.d with the value of ss.b[ss.a] (that is, ’s’), and in

struct X { int i, j, k = 42; };
X a[] = { 1, 2, 3, 4, 5, 6 };
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };

a and b have the same value —end example ]

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, glad to see c++1y is making thing easier for me.
It took me a while to figure out, but VS 2015 does not support this feature, according to msdn.microsoft.com/en-us/library/hh567368.aspx#cpp14table
3

(Answer valid in C++1y, only!)

According to paragraph #7 of section "8.5.1 Aggregates" (Working Draft N3691 Date: 2013-05-16)

7 If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equalinitializer, from an empty initializer list (8.5.4).

And below the quote there is an example

[ Example: struct S { int a; const char* b; int c; int d = b[a]; }; 
S  ss = { 1, "asdf" };
 initializes ss.a with 1, ss.b with "asdf", ss.c
with the value of an expression of the form int{} (that is, 0), and
ss.d with the value of ss.b[ss.a] (that is, ’s’),

So in your example p.y will be initialized by 10.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.