Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default-initialized vs. Value-initialized

From this answer, In C++03, a POD type gets default initialized if () is omitted otherwise it is value-initialized.

// POD type
struct foo {
     int x;
};

// value-initialized
new foo();

But if a user-defined constructor is provided, is any of the objects below will be considered as default or value-initialized ?

// non-POD type
struct bar {
     bar(int x = 0):x(x) {}
     int x;
};

new bar();
new bar(42);
like image 854
cpx Avatar asked Nov 20 '11 18:11

cpx


2 Answers

In C++03, a POD type gets default initialized if () is omitted otherwise it is value-initialized.

That is not exactly what happens. According to the C++03 spec, section 8.5/9, if no initializer is specified for a non-static POD-type object, then it and its sub-objects "have an indeterminate initial value". That is not the same thing as default-initialization. Default-initialization is the same thing as value-initialization for a POD-type, which would mean the object is zero-initialized (8.5/5), but that can only happen with the presence of an empty initializer (i.e., empty-parenthesis per 8.5/7). Thus you can only default and/or value-initialize a POD-type with an empty initializer. Default initialization for a non-static POD-type does not happen when no initializer is specified.

In your second example, with the non-POD type that has the user-defined constructor, default-initialization would technically take place if you omitted the value-initializer (parenthesis) symbols. In other words:

bar* ptr_a = new bar; //default initialization
bar* ptr_b = new bar(); //value initialization

Keep in mind though that with both non-POD struct or class-types, if there is a user-defined constructor, default-initialization and value initialization, per 8.5/5, both call the user-defined constructor. So in the end, with the type bar as you've declared it, default and value initialization end up doing the same thing.

like image 107
Jason Avatar answered Sep 29 '22 05:09

Jason


If your class has a user-defined default constructor, then both default and value initialization cause that constructor to be called. Whatever happens next is up to the constructor:

struct UDT
{
  int a;
  int b;
  Foo c;
  Foo d;
  UDT() : a(), c() {}
};

Both default and value initialization of an object of class UDT will cause UDT::a and UDT::c to be value-initialized (so a is zero) because the initializer list says so, while UDT::b and UDT::d are themselves default-initialized (so b is uninitialized, and for d apply the same logic recursively).

For details on initialization, see 8.5, and on initializer lists see 12.6.2 (esp. clause 8).

like image 25
Kerrek SB Avatar answered Sep 29 '22 06:09

Kerrek SB