Creating a Stack Object in C ++ - Alternative Syntax

Possible duplicate:
What do the following words in C ++ mean: zero, default initialization, and value?

I am confused about a problem in C ++.

When creating an object on the stack using the default constructor, I thought that 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, while the second leaves the field uninitialized. So my questions are:

  • Why is this so? I thought that fields in C ++ should not be automatically initialized.
  • Are there any other differences between the two syntaxes?
  • Do these syntax variants have separate names to distinguish them from each other?

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

+4
source share
2 answers

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

An object whose initializer is an empty set of brackets, i.e. (), must be initialized with a value.

And from § 8.5 / 5:

To initialize a value of 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 initialization is poorly formed if T does not have an available default constructor);
  • if T is a non-unit type of a class without a constructor declared by the user, then each non-static data element and component of the base class T is initialized with value initialization;
  • If T is an array type, then each element is initialized with a value;
  • otherwise the object is initialized to zero

For zero initialization of an object of type T means:

  • if T is a scalar type, the object is set to 0 (zero) converted to T ;
  • if T is a type of non-unit class, each non-static data member and each subobject of the base class are initialized to zero;
  • if T is a union type, objects first called a data element) are initialized to zero;
  • If T is an array type, each element is initialized to zero;
  • If T is a reference type, initialization is not performed.

In the second, you declare b so that it is initialized by default if MyClass not a POD type - §8.5 / 5:

To initialize an object of type T by default:

  • if T is a class type not POD, the default constructor for T is called (and initialization is poorly formed if T does not have an available default constructor);
  • if T - array type, each element is initialized by default;
  • otherwise, the object is initialized to zero.

However, since MyClass is a POD type, b is not initialized - §8.5 / 9:

If an object does not have an initializer, and the object has a (possibly cv-qualified) non-POD class type (or its array), the object should be initialized by default; if the object is of type const-type, the base type of the class must have a default constructor declared by the user. Otherwise, if an initializer is not specified for a non-static object, the object and its subobjects, if any, have an undefined initial value ; if an object or any of its subobjects is of type const-specific, the program is poorly formed.

+7
source

Basically, this is a (relatively) simple WTF in a language where primitive types will not be initialized by default. The first syntax explicitly initializes them, the second does not. Custom types will always be initialized, so this only makes sense if you do not initialize it in the constructor, and it will be a mistake if you do not call the init functions of the UDT that need them.

UDTs that don't do anything crazy should not require the first syntax, and it’s normal to use the second.

-1
source

All Articles