Belloc
Belloc

Reputation: 6390

Need some clarification with 8.5.p7 in the C++11 Standard

Paragraph 8.5p7 of the C++11 Standard states:

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.

I have a problem understanding the characters in bold above. How the additional calling of T's implicit default constructor could alter the zero-initialization, that has just occurred in this case?

Upvotes: 12

Views: 359

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126526

Here's a concrete example:

class A {
    int a;
public:
    A() : a(1) {}
};

class B {
    int b;
    A c;
};

B falls in this category - it's a non-union class type without a user-provided constructor. So if a B is value-initialized, it will first be zero-initialized (so both b and c.a will be set to 0), and then the default constructor will be called (which will call A's constructor and set c.a to 1).

By the as-if rule, these might be combined into a single step by the optimizer (which will set b to 0 and c.a to 1), as no-one can ever see the object between the zero initialization and the default constructor.

Upvotes: 16

bames53
bames53

Reputation: 88225

struct S {
    int a, b;
    S() : b(10) {}
};

struct T {
  S s;
};

int main() {
    S s{};
    T t{};
}

t is value initialized and T does not have a user-provided constructor. However T's implicitly declared default constructor is not trivial.

s is also value initialized but S has a user provided constructor.

s.a will have an indeterminate value. but t.s.a is zero due to the zero initialization that precedes the call of the default constructor. Both s.b and t.s.b are set to the value 10.

Upvotes: 4

Igor Tandetnik
Igor Tandetnik

Reputation: 52621

T may not have its own explicit default constructor, but it may derive from U that does, and/or have a member of class type V that does.

Upvotes: 5

Related Questions