How do I ensure that a data member is initialized to a value instead of remaning default-initialized?
Asked Answered
M

4

25

I was asking myself something this morning, and I can't find the words to properly "google" for it:

Lets say I have:

struct Foo
{
  int bar;
};

struct Foo2
{
   int bar;
   Foo2() {}
};

struct Foo3
{
   int bar;
   Foo3() : bar(0) {}
};

Now, if I default-initialize Foo, Foo2 and Foo3:

Foo foo;
Foo2 foo2;
Foo3 foo3;

In which case(s) is the bar member properly initialized, meaning that its value isn't indeterminate?


Note: Foo3 obviously initialized. It is only shown here to display the difference to Foo2, so the question is mainly about the first two.

Mckinleymckinney answered 6/6, 2011 at 12:2 Comment(3)
Just to be clear, are foo, foo2 and foo3 in the global namespace scope or in a function?Aboral
@Charles Bailey: This is sample code I just written for the purpose of my question: it has no reality whatsoever. However, I was not aware this could make a difference. Could you tell me more about that ?Mckinleymckinney
I am not sure, but this looks like a related question: #3931341Xmas
R
32

Only foo3 will be in all contexts. foo2 and foo will be if they are of static duration. Note that objects of type Foo may be zero initialized in other contexts:

Foo* foo = new Foo(); // will initialize bar to 0
Foo* foox = new Foo; // will not initialize bar to 0

while Foo2 will not:

Foo2* foo = new Foo2(); // will not initialize bar to 0
Foo2* foox = new Foo2; // will not initialize bar to 0

that area is tricky, the wording as changed between C++98 and C++03 and, IIRC, again with C++0X, so I'd not depend on it.

With

struct Foo4
{
   int bar;
   Foo4() : bar() {}
};

bar will always be initialized as well.

Remand answered 6/6, 2011 at 12:15 Comment(2)
Can you please explain what you meant by foo2 and foo will be if they are of static duration.?Daguerreotype
@Cupidvogel, static Foo foo;.Petromilli
D
10

Since bar is a built-in type its default initialization will be undefined for Foo1 and Foo2. If it would have been a custom type, then the default constructor would have been called, but here it's not the case.

Lesson: always initialize your variables.

Dearr answered 6/6, 2011 at 12:5 Comment(4)
If I get you well, a primitive or POD type is never implicitely initialized ?Mckinleymckinney
Well, not all compilers do, this question's answers might help: #2417565Dearr
@ereOn: implicitly initialized is not a used term, so the answer would depend on your particular interpretation of the term. default-initailization will not set the values for POD types, but value-initialization will. That is, POD p; does not guarantee values, but POD p = {}; (aggregate initialization), or POD p = POD(); or POD p(( POD() )); will value initialize all members to 0 (converted to each member's type)Prelusive
@David: Indeed my terminology is a bit off here. Thanks for the explanations, makes much more sense to me now.Mckinleymckinney
M
1

Case 3 is the proper way, with a member initialization list.

None of the first two will be properly initialized, since you don't give them an initial value (exactly like a variable only defined is not initialized).

Muskrat answered 6/6, 2011 at 12:5 Comment(1)
Proper sure, I always do like that anyway. But my question was more about the two others, that I sometimes encounter and for which I can't emit any judgment.Mckinleymckinney
S
1

For pod-types, the default initialization is zero-initialization.

Therefore:

Foo() : b() {} is the same as Foo() : b(0) {}

I can't find the respective part of the C++ standard, but if you skip the initializer completely, then POD types shouldn't be default-initialized (unlike non-POD types, which are).

Therefore in your case, only the third example is correctly initialized.

Sounder answered 6/6, 2011 at 12:14 Comment(1)
As for me it is not correct - "Scalars and POD types with dynamic storage duration were considered to be not initialized" (en.cppreference.com/w/cpp/language/default_initialization) C++2003, 8.5.5 nothing about POD in case of default-initMeningitis

© 2022 - 2024 — McMap. All rights reserved.