I cannot understand the behavior of gcc 4.8.1 or Visual Studio 2015 with respect to default initialization versus value initialization.
It doesn\'t help that I\'m tr
Foo foo;
This default-initializes foo
, and since Foo
's default constructor is trivial, it effectively doesn't initialize it at all, so foo._bar
can hold any value (including 0).
Foo()
This value-initializes the temporary object, which in case of trivial default constructor means zero-initialization, so Foo()._bar
is equal to 0.
The logic is quite simple:
Default initialisation, of classes like this without user-defined constructors, does nothing, leaving each trivial member with an indeterminate value.
Value initialisation will zero-initialise each member.
In the first case, you're printing:
Foo foo;
Foo()
bar b;
The third one happens to be zero; perhaps because it reuses the storage of the temporary value-initialised Foo
.
In the second case, you're printing the indeterminate values of two default-initialised objects. Coincidentally, they have zero values in one case but not the other.
Both programs have undefined behaviour, since they use uninitialised values.
n3376 quotes
8.5/11
If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ]
8.5/6
To default-initialize an object of type T means: if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
8.5/10
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
8.5/7
To value-initialize an object of type T means:
...
otherwise, the object is zero-initialized.
8.5/5
To zero-initialize an object or reference of type T means: if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
So, in your case, there are nor static storage duration variables, nor thread-local variables, so objects foo
and b
will be default-initialized, that means, that constructor will be called. Default-constructor (not user-defined) will not initialize members and in members will be arbitrary garbage and this arbitrary garbage may be 0 (thanks to Jarod42 for point this in comment).
And Foo().printBar();
should print 0, since object is zero-initialized.