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 instantiate Foo, Foo2 and Foo3:

Foo foo;
Foo2 foo2;
Foo3 foo3;

In which case(s) is the bar member properly initialized ?

(Well Foo3 obviously explicitely initialize it and is only showed here to explicit the difference with Foo2 so the question is mainly about the first two.)

Thank you ! :)

Jonas
  • 121,568
  • 97
  • 310
  • 388
ereOn
  • 53,676
  • 39
  • 161
  • 238
  • Just to be clear, are `foo`, `foo2` and `foo3` in the global namespace scope or in a function? – CB Bailey Jun 06 '11 at 12:09
  • @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 ? – ereOn Jun 06 '11 at 12:12
  • I am not sure, but this looks like a related question: http://stackoverflow.com/questions/3930841/is-there-a-way-to-make-a-c-struct-value-initialize-all-pod-member-variables – Asha Jun 06 '11 at 12:18

4 Answers4

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.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
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.

Jesse Emond
  • 7,180
  • 7
  • 32
  • 37
  • If I get you well, a primitive or POD type is never **implicitely initialized** ? – ereOn Jun 06 '11 at 12:08
  • Well, not all compilers do, this question's answers might help: http://stackoverflow.com/questions/2417065/c-does-the-default-constructor-initialize-built-in-types – Jesse Emond Jun 06 '11 at 12:11
  • 2
    @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) – David Rodríguez - dribeas Jun 06 '11 at 12:21
  • @David: Indeed my terminology is a bit off here. Thanks for the explanations, makes much more sense to me now. – ereOn Jun 06 '11 at 12:27
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).

CharlesB
  • 86,532
  • 28
  • 194
  • 218
  • 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. – ereOn Jun 06 '11 at 12:06
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.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • As for me it is not correct - "Scalars and POD types with dynamic storage duration were considered to be not initialized" (http://en.cppreference.com/w/cpp/language/default_initialization) C++2003, 8.5.5 nothing about POD in case of default-init – Konstantin Burlachenko Feb 06 '15 at 11:23