Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POD members default initialization without braces

Given code:

struct Test {
    int a = 1;
    int b = 2;
};

Test test1;
Test test2{};

For test2 I am sure, that test2.a == 1 and test2.b == 2. Is it guaranteed (or not) the same for test1 (without {})?

like image 823
vladon Avatar asked Apr 17 '17 16:04

vladon


3 Answers

The line

Test test1;

is equivalent to an initialization with a default constructor which, in the absence of a hand-written one with an explicit initialization list and with no Test() = deleted; would end up setting the two members to their specified initial values 1 and 2.

A “default constructor” is a constructor that can be called with no arguments, which is exactly the case with the above statement.

You can read up on the rules for default constructors in the standard - go to § 12.1 section 4:

A default constructor for a class X is a constructor of class X that can be called without an argument...

And further in section 5:

A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odrused (3.2) to create an object of its class type (1.8)...

like image 90
YePhIcK Avatar answered Nov 14 '22 21:11

YePhIcK


test1 is also guaranteed to have its member a initialized to 1 and its member b to be initialized to 2.

From C++11 FAQ, In-class member initializers:

The basic idea for C++11 is to allow a non-static data member to be initialized where it is declared (in its class). A constructor can then use the initializer when run-time initialization is needed. Consider:

class A {
  public:
    int a = 7;
};

This is equivalent to:

class A {
  public:
    int a;
    A() : a(7) {}
};
like image 23
R Sahu Avatar answered Nov 14 '22 21:11

R Sahu


Yes, they have the same effect here.

For the 1st case, it's default initialization,

if T is a class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;

That means the implicitly-defined default constructor will be invoked; it doesn't use any member initializer list and then default member initializer would take effect to initialize the data members.

For the 2nd case, it's aggregate initialization,

If the number of initializer clauses is less than the number of members and bases (since C++17) or initializer list is completely empty, the remaining members and bases (since C++17) are initialized by their default initializers, if provided in the class definition, and otherwise (since C++14) ...

So the default member initializer would take effect to initialize the data members, too.

like image 41
songyuanyao Avatar answered Nov 14 '22 19:11

songyuanyao