What Do the Following Phrases Mean in C++: Zero-, Default- and Value-Initialization

What do the following phrases mean in C++: zero-, default- and value-initialization?

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):

  • Do the parentheses after the type name make a difference with new?

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;
}

Difference between default-initialize and value-initialize? [duplicate]

According to the standard (8.5/4,5):

To default-initialize an object of
type T means:

— if T is a non-POD
class type 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;96)

— if T is an
array type, then each element is
value-initialized;

— otherwise, the
object is zero-initialized

What does 'value initializing' something mean? [duplicate]

A declared variable can be Zero Initialized, Value Initialized or Default Initialized.

In your example:

Info *p = new Info();    <------- Value Initialization
Info *p = new Info; <------- Default Initialization

The C++03 Standard 8.5/5 aptly defines each:

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

C++ default initialization and value initialization: which is which, which is called when and how to reliably initialize a template-type member

Not so hard:

A x;
A * p = new A;

These two are default initialization. Since you don't have a user-defined constructor, this just means that all members are default-initialized. Default-initializing a fundamental type like int means "no initialization".

Next:

A * p = new A();

This is value initialization. (I don't think there exists an automatic version of this in C++98/03, though in C++11 you can say A x{};, and this brace-initialization becomes value-initialization. Moreover, A x = A(); is close enough practically despite being copy-initialization, or A x((A())) despite being direct-initialization.)

Again, in your case this just means that all members are value-initialized. Value initialization for fundamental types means zero-initialization, which in turn means that the variables are initialized to zero (which all fundamental types have).

For objects of class type, both default- and value-initialization invoke the default constructor. What happens then depends on the constructor's initializer list, and the game continues recursively for member variables.

Value initialization on explicit constructor call in C++? [duplicate]

Firstly, what happens actually if no constructor is called

A constructor for a class-type is always called when an object is constructed, be it user-defined or compiler-generated. The object is initialized, but the members can remain un-initialized. This makes the second part of the question obsolete.

Second, is there documentation that supports/mentions/explains this behaviour ?

The all-mighty standard.

Meaning of default initialization changed in C++11?

The final effects are almost the same. In C++03, the use of default-initialize was restricted to non-POD class type, so the last point never applied. In C++11, the standard simplifies the wording by eliminating the condition with regards to where default-initialization was used, and changes the definition of default-initialization to cover all of the cases in a way to correspond what happened before.

Is this aggregate initialization or default initialization in C++?

Empty parentheses or braces (T() or T{}) perform value initialization. The exception would be the case where the type is an aggregate in which case aggregate initialization would be used. Since int is not an aggregate, it will be value initialized and since it's not a class nor an array, value initialization will do zero-initialization.

You were wondering why it doesn't work in C. Such syntax simply doesn't exist in C, see this answer.



Related Topics



Leave a reply



Submit