4

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

I am confused about an issue in C++.

When creating an object on the stack using the default constructor, I thought either one of the following two syntax notations would give the same result:

class MyClass { public: int i; }
int main()
{
  MyClass a = MyClass();
  MyClass b;
}

However, the first syntax initializes the field to zero, whereas the second one leaves the field uninitialized. So my questions are:

  1. Why is this so? I thought fields in C++ were not supposed to be automatically initialized.
  2. Is there any other differences between the two syntaxes?
  3. Do these syntax variations have separate names to distinguish them from each other?

I’m currently using Microsoft Visual C++ 2010 Express. Thanks!

Community
  • 1
  • 1
Mike
  • 41
  • 3
  • 1
    You're seeing C++03 behavior. In C++98 they would both leave it uninitialized if it didn't have a constructor. There was a nearly identical question a couple days ago. – Mark B Jun 28 '11 at 19:23
  • @Mark B: I completely disagree. You would have to know those phrases to get back that question. It's relevant, absolutely, but not a duplicate. – Puppy Jun 28 '11 at 19:27
  • 2
    @DeadMG: Nobody is blaming Mike for not finding this question, but his is still answered by the answers to the other question, which is why I think this should indeed be closed as a dupe. ("This question covers exactly the same ground as earlier questions on this topic.") – sbi Jun 28 '11 at 19:30

2 Answers2

7

In the first, you copy-initialize a from a value-initialized instance of MyClass. From the C++03 standard, §8.5/7:

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

And from §8.5/5:

To value-initialize an object of type T means:

  • if T is a class type with a user-declared constructor, 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

To zero-initialize an object of type T means:

  • if T is a scalar type, 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.

In the second, you declare b in a manner that would cause it to be default-initialized if MyClass were not a POD type -- §8.5/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.

However, because MyClass is a POD type, b is uninitialized -- §8.5/9:

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.

Community
  • 1
  • 1
ildjarn
  • 59,718
  • 8
  • 115
  • 201
-1

Basically, this is a (relatively) simple WTF in the language, where primitive types will not be initialized by default. The first syntax explicitly initializes them- the second doesn't. User-defined types will always be initialized, so it's only meaningful if you don't initialize it in the constructor, and it will be an error if you don't call the init functions of UDTs that need them.

UDTs that do not do anything insane should not require the first syntax and it's normal to use the second.

Puppy
  • 138,897
  • 33
  • 232
  • 446