197

What do the following phrases mean in C++:

  • zero-initialization,

  • default-initialization, and

  • value-initialization

What should a C++ developer know about them?

Destructor
  • 13,235
  • 8
  • 48
  • 108
Bill
  • 10,817
  • 6
  • 41
  • 52
  • 1
    This is related to (but not identical to) http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new – Steve Jessop Dec 07 '10 at 17:20
  • 22
    There's more! The complete list of initializations: Value, direct, copy, list (C++11 new intro), aggregate, reference, zero, constant and default; http://en.cppreference.com/w/cpp/language/initialization lists all of them with examples :) – legends2k May 07 '13 at 14:29

2 Answers2

89

C++03 Standard 8.5/5:

To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared 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 non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed. If T is a cv-qualified type, the cv-unqualified version of T is used for these definitions of zero-initialization, default-initialization, and value-initialization.

Kirill V. Lyadvinsky
  • 89,955
  • 22
  • 127
  • 208
  • 19
    This might be outdated for C++11. [cppreference.com](http://en.cppreference.com/w/cpp/language/default_initialization) states that default initialization _does not_ zero-initialize members (only value initialization does). – Alexei Sholik Jul 09 '13 at 12:05
  • 3
    @android raises an important point, which I don't see answered elsewhere, so I've made a new question. http://stackoverflow.com/questions/22233148/meaning-of-default-initialization-changed-in-c11 – Adrian McCarthy Mar 06 '14 at 18:40
66

One thing to realize is that 'value-initialization' is new with the C++ 2003 standard - it doesn't exist in the original 1998 standard (I think it might be the only difference that's more than a clarification). See Kirill V. Lyadvinsky's answer for the definitions straight from the standard.

See this previous answer about the behavior of operator new for details on the the different behavior of these type of initialization and when they kick in (and when they differ from c++98 to C++03):

The main point of the answer is:

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, or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • In C++1998 there are 2 types of initialization: zero and default
  • In C++2003 a 3rd type of initialization, value initialization was added.

To say they least, it's rather complex and when the different methods kick in are subtle.

One thing to certainly be aware of is that MSVC follows the C++98 rules, even in VS 2008 (VC 9 or cl.exe version 15.x).

The following snippet shows that MSVC and Digital Mars follow C++98 rules, while GCC 3.4.5 and Comeau follow the C++03 rules:

#include <cstdio>
#include <cstring>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    std::memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    std::printf( "m  is %d\n", pB->m);
    return 0;
}
L. F.
  • 16,219
  • 7
  • 33
  • 67
Michael Burr
  • 311,791
  • 49
  • 497
  • 724
  • 1
    Not that it matters for `int`, but `m()` on the third line value initializes m. Important if you change `int m;` to `B m;`. :) – Johannes Schaub - litb Oct 23 '09 at 14:46
  • Right - `A` and `C` aren't used in this example (they're carried over from the other linked answer). Even though C++98 and C++03 use different terminology when describing how `A` and `C` are constructed, the result is the same in both standards. Only `struct B` results in different behavior. – Michael Burr Oct 23 '09 at 14:55
  • 1
    what i meant is that if you change C to `struct C { C() : m() {}; ~C(); B m; };`, then you will have `m.m` be 0. But if it would default-initialise `m` like you say C++03 does, then `m.m` would be not initialized like in C++98. – Johannes Schaub - litb Sep 27 '10 at 14:44
  • 1
    Additional interesting comments on MSVC handling of this feature: http://stackoverflow.com/questions/3931312/value-initialization-and-non-pod-types/3931589#3931589 – Brent Bradburn Jul 26 '11 at 21:45
  • Which initialization takes place when you declare your type as a local variable, i.e. at the stack? – André Puel Mar 21 '13 at 13:38
  • Here's a great reference on [`value-initialization`](http://en.cppreference.com/w/cpp/language/value_initialization) and [`default-initialization`](http://en.cppreference.com/w/cpp/language/default_initialization). – Alexei Sholik Jul 09 '13 at 12:03
  • 1
    g++ 4.4.7 20120313 for Red Hat 4.4.7-18 initializes m to 0 with your example (compiling with -std=c++98). – Jean Apr 27 '18 at 08:57
  • g++ 10.2.0 for Ubuntu initializes m to 0 with your example (compiling with -std=c++98) as well – HEKTO Feb 18 '21 at 20:13