3

I came upon this interesting answer when our team was dealing with a valgrind warning about unitialized members of a POD in our C++ code:

https://stackoverflow.com/a/5914697/629530

Restating the salient points, consider the following POD structure in C++:

struct C
{
    int x; 
    int y;
};

The following invocations of constructing an object of type C invokes the default constructor and the members are initialized with that default constructor (again, copying the code and comments from Martin York's answer):

C  c = C();      // Zero initialize using default constructor
C  c{};          // Latest versions accept this syntax.
C* c = new C();  // Zero initialize a dynamically allocated object.

Makes sense. Martin York goes on to point out that the with the following declarations, however, the members of c are not initialized via a constructor and therefore contain undefined data:

C  c;            // members are random
C* c = new C;    // members are random (more officially undefined).

That's interesting. I had used braced-init-list initialization of POD types before, but I didn't realize that C c; would not call the default constructor for a POD type. His answer satisfies the question, but I'd like to know specifically what is instantiated when the latter, non-default constructed c objects are declared. Specifically, the following would be helpful to me:

  1. What is the official name for this non-default initialization of POD types? I'm having trouble googling for this mechanism because I don't know its name.
  2. If the POD type has something less trivial than an int-type, such as a std::string, is the memory for that member also initialized with undefined values? Or is the default constructor for a std::string called for that member?

Update.

Thanks for the input. This has been duplicated to a question with this single answer: https://stackoverflow.com/a/8860787/629530

According to that answer (and the answers to the question it is duplicated to), a declaration of the form without a parentheses is called "default initialized":

Info *p = new Info;      <------- Default Initialization

For default initialization, these points about initialization are made:

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.

I might be misunderstanding something, but the struct named C proposed above is a POD type that is not an array. Thus it should be zero initialized? The members are not, however, zero initialized but contain undefined values. How do I reconcile this?

firebush
  • 5,180
  • 4
  • 34
  • 45
  • Question 1. Are you angling for `value initialization`? Question 2 should be asked separately, without this much of a preamble (and immediately closed as a duplicate of a duplicate of a duplicate) – SergeyA Aug 13 '19 at 18:27
  • See also: https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special – Alecto Irene Perez Aug 13 '19 at 18:30

1 Answers1

4

default-initialize an object of type T means:

... otherwise, the object is zero-initialized.

No.

Your first linked answer is correct about C++11 onwards, and this is called default-initialization. It's different to default-construction or value initialization.

The second linked answer was probably correct for C++03, but is wrong for C++11 onwards (even though it was written in 2012). I don't have a copy of the '03 standard to verify, and it was a long time ago.

The effects of default initialization are:

  • if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;

  • if T is an array type, every element of the array is default-initialized;

  • otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.


Local copy of N4659 agrees with the summary above:

11.6 Initializers [dcl.init]

...

(7.3) Otherwise, no initialization is performed

The section on new-expressions even refers to 11.6 and then says

Note: If no initialization is performed, the object has an indeterminate value.— end note


Current draft has

9.3 Initializers [dcl.init]

...

(7.3) Otherwise, no initialization is performed.

Community
  • 1
  • 1
Useless
  • 64,155
  • 6
  • 88
  • 132
  • This is perfect. The https://en.cppreference.com/w/cpp/language/default_initialization link is exactly what I was looking for when I posted this question. Thanks! – firebush Aug 14 '19 at 16:20