What do the following phrases mean in C++:
zero-initialization,
default-initialization, and
value-initialization
What should a C++ developer know about them?
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;
}