Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-triviality of class type due to presence of default member initializer(s)

All standard references below refers to N4659: March 2017 post-Kona working draft/C++17 DIS.


As one may expect, the use of default member initializers for non-static data members makes a class non-trivial:

// Well-formed according to both GCC and Clang (-std=c++17).
#include <type_traits>

struct Trivial { int a; int b; };
struct NotTrivial { int a; int b{0}; };

static_assert(std::is_trivial_v<Trivial>, "");
static_assert(!std::is_trivial_v<NotTrivial>, "");

int main() {}

What passage of the (C++17) standard governs that NotTrivial is a non-trivial class?

like image 936
dfrib Avatar asked Oct 23 '25 22:10

dfrib


1 Answers

All standard references below refers to N4659: March 2017 post-Kona working draft/C++17 DIS.


[class]/6 governs what is a trivial class [extract]:

[...] A trivial class is a class that is trivially copyable and has one or more default constructors, all of which are either trivial or deleted and at least one of which is not deleted. [...]

Let's denote the trivial class requirements as follows:

  • (A) the class is trivially copyable, and
  • (B) all the default constructors of the class are either trivial or deleted, and
  • (C) the class has at least one non-deleted default constructor.

As will be shown below, NonTrivial fulfills requirements (A) and (C), but fails requirement (B), and is thus not trivial.


Requirement (A): trivially copyable [fulfilled]

Requirement (A) is governed by [class]/6:

A trivially copyable class is a class:

  • (6.1) where each copy constructor, move constructor, copy assignment operator, and move assignment operator ([class.copy], [over.ass]) is either deleted or trivial,
  • (6.2) that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and
  • (6.3) that has a trivial, non-deleted destructor.

where the first sub-requirement (6.1) covering triviality of constructors and assignment operators is governed by [class.copy.ctor]/11 and [class.copy.assign]/9, respectively:

[class.copy.ctor]/11

A copy/move constructor for class X is trivial if it is not user-provided and if:

  • (11.1) class X has no virtual functions and no virtual base classes, and
  • (11.2) the constructor selected to copy/move each direct base class subobject is trivial, and
  • (11.3) for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;

otherwise the copy/move constructor is non-trivial.

[class.copy.assign]/9

A copy/move assignment operator for class X is trivial if it is not user-provided and if:

  • (9.1) class X has no virtual functions and no virtual base classes, and
  • (9.2) the assignment operator selected to copy/move each direct base class subobject is trivial, and
  • (9.3) for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;

otherwise the copy/move assignment operator is non-trivial.

which are all fulfilled by NonTrivial.

The second sub-requirement (6.2) covering existence of constructors and assignment operators, when restricted to implicitly declared special functions (as is the case for this example), is governed by [class.copy.ctor]/6 and [class.copy.assign]/2, respectively:

[class.copy.ctor]/6

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted. [...]

[class.copy.assign]/2

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted. [...]

Thus, a copy constructor and copy assignment operator will be implicitly declared for NonTrivial. It follows from [class.copy.ctor]/8 and [class.copy.assign]/4 4that the same holds for for the move constructor and move assignment operator, respectively. Thus, NonTrivial fulfills the sub-requirement (6.2).

The third sub-requirement (6.3) is governed by [class.dtor]/6:

A destructor is trivial if it is not user-provided and if:

  • (6.1) the destructor is not virtual,
  • (6.2) all of the direct base classes of its class have trivial destructors, and
  • (6.3) for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.

Otherwise, the destructor is non-trivial.

which is fulfilled by NonTrivial, and thus requirement (A) holds for NonTrivial.


Requirement (B): trivial or deleted default constructors [NOT fulfilled]

As governed by [class.ctor]/4 [extract]:

[...] If there is no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared as defaulted ([dcl.fct.def]).

a default constructor will be implicitly declared for the NonTrivial class. However, as governed by [class.ctor]/6, particularly [class.ctor]/6.2, this implicitly declared default constructor is not trivial:

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

  • [...]
  • (6.2) no non-static data member of its class has a default member initializer ([class.mem]), and [...]

And thus the NonTrivial class fails the requirement (B), and is thus not trivial.

We may note that the clause [class.ctor]/6.2 originated from the original proposal for non-static data member initializers, N2628, which proposed adding

no non-static data member of its class has an assignment-initializer, and

as an additional triviality requirement to [class.ctor].


Requirement (C): existence of a default constructor [fulfilled]

For completeness, we may note that the NonTrivial class fulfills requirement (C), as per [class.ctor]/4 (quoted to in the section above).

like image 89
dfrib Avatar answered Oct 25 '25 13:10

dfrib



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!