Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value initialization

$8.5/7 states that

— 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.

I am unable to appreciate the last part of this statement "if T’s implicitly-declared default constructor is non-trivial, that constructor is called."

Can someone please explain this with an example?

class A
{
    int x;
};

class B : A {};

B b{};

I think B in the code above is having a non-trivial constructor. But how do I observe call to B's implicitly declared constructor and make sure that my compiler is calling it?

like image 765
Chubsdad Avatar asked Jul 01 '26 08:07

Chubsdad


2 Answers

I think B in the code above is having a non-trivial constructor.

In your example, the constructor is trivial.

Looking at the conditions in C++11 12.1/5, neither class has a user-declared constructor, virtual functions, virtual base classes, members with initialisers, or members of class type; A has no base classes and B only has a trivial base class.

But how do I observe call to B's implicitly declared constructor and make sure that my compiler is calling it?

One way to make a class with an implicit, but non-trivial, default constructor is to have a non-trivial member or base class:

struct A {
    // A user-declared constructor is non-trivial
    A() {std::cout << "Construct A\n";}
};

struct B : A {};

Now you can (indirectly) observe the implicit constructor of B being called, by observing the side-effect when it calls the constructor of A.

like image 142
Mike Seymour Avatar answered Jul 03 '26 06:07

Mike Seymour


Explanation after N3797:

A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.

Therefore, since you don't declare a default constructor for B, it is not user-provided. The following then applies:

A default constructor is trivial if it is not user-provided and if:

— its class has no virtual functions (10.3) and no virtual base classes (10.1), and

— no non-static data member of its class has a brace-or-equal-initializer, and

— all the direct base classes of its class have trivial default constructors, and

— for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.

So it is indeed trivial, since we can apply the same procedure recursively for A.

Other examples:

struct A { A() = default; }; // Trivial default constructor!
struct A { A() = delete; }; // Also trivial!
struct A { A(); }; // Can't be trivial!

struct B { virtual void f(); }
struct A : B {}; // Non-trivial default constructor.

struct B {};
struct A : virtual B {}; // Non-trivial default constructor.
like image 34
Columbo Avatar answered Jul 03 '26 07:07

Columbo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!