c++c++11c++14c++03c++98

Default, value and zero initialization mess


I am very confused about value- & default- & zero-initialization. and especially when they kick in for the different standards C++03 and C++11 (and C++14).

I am quoting and trying to extend a really good answer Value-/Default-/Zero- Init C++98 and C++03 here to make it more general as it would help a lot of users if somebody could help fill out the needed gaps to have a good overview about what happens when?

The full insight by examples in a nutshell:

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.

Assume:

struct A { int m; };                     
struct B { ~B(); int m; };               
struct C { C() : m(){}; ~C(); int m; };  
struct D { D(){}; int m; };             
struct E { E() = default; int m;}; /** only possible in c++11/14 */  
struct F {F(); int m;};  F::F() = default; /** only possible in c++11/14 */

In a C++98 compiler, the following should occur:

In a C++03 conformant compiler, things should work like so:

Italic values and ? are uncertainties, please help to correct this :-)

In a C++11 conformant compiler, things should work like so:

??? (please help if I start here it will anyway go wrong)

In a C++14 conformant compiler, things should work like so: ??? (please help if I start here it will anyway go wrong) (Draft based on answer)


Solution

  • C++14 specifies initialization of objects created with new in [expr.new]/17 ([expr.new]/15 in C++11, and the note wasn't a note but normative text back then):

    A new-expression that creates an object of type T initializes that object as follows:

    • If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ]
    • Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.

    Default-initialization is defined in [dcl.init]/7 (/6 in C++11, and the wording itself has the same effect):

    To default-initialize an object of type T means:

    • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
    • if T is an array type, each element is default-initialized;
    • otherwise, no initialization is performed.

    Thus


    † Well, this paragraph has slightly different wording in C++11, which does not alter the result:

    To value-initialize an object of type T means:

    • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
    • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
    • if T is an array type, then each element is value-initialized;
    • otherwise, the object is zero-initialized.