Parent
is a POD-type (plain old data type). It has no constructors or destructors (besides the implicit, which are trivial), complex members, etc. Its just a struct with scalars or other POD-type members. When you do this:
struct Child : Parent
{
int b;
Child () {
printf("child constructor\n");
}
}
you're simply constructing the child object. No relevant construction of Parent
is taking place. The base type undergoes default initialization:
C++11 § 8.5,p11
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.
For your POD-type, this means:
C++11 § 8.5,p6
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);
if T is an array type, each element is default-initialized;
otherwise, no initialization is performed.
But when you do this:
struct Child : Parent
{
int b;
Child () : Parent () {
printf("child constructor\n");
}
}
something different happens: You're invoking value-initialization of the Parent
base type. due to the ()
.
C++11 § 8.5,p10
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
For POD-types (of which Parent
is one) value-initialization will eventually zero-initialize the members.
C++11 § 8.5,p7
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
if T is an array type, then each element is value-initialized;
otherwise, the object is zero-initialized.
Thus a
is zero in the second case, but not in the first. (well, it could be zero in the first, you can't really say; its value is indeterminate until you assign something to it).