Title
Trivial special member functions that cannot be implicitly defined
Status
cd2
Section
_N4750_.15.8 [class.copy]
Submitter
James Widman

Created on 2007-12-14.00:00:00 last changed 144 months ago

Messages

Date: 2010-03-15.00:00:00

[Voted into WP at March, 2010 meeting as part of document N3079.]

Date: 2009-10-15.00:00:00

Proposed resolution (October, 2009):

  1. Change 9.5 [dcl.fct.def] paragraph 9 as follows:

  2. ...Only special member functions may be explicitly defaulted. Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall define them as if they had provide implicit definitions for them (11.4.5 [class.ctor], 11.4.7 [class.dtor], _N4750_.15.8 [class.copy]), which might mean defining them as deleted. A special member function that would be implicitly defined as deleted may be explicitly defaulted only on its first declaration, in which case it is defined as deleted. A special member function is user-provided if it is user-declared and not explicitly defaulted on its first declaration. A user-provided explicitly-defaulted function is defined at the point where it is explicitly defaulted. [Note:...
  3. Change 11.4.5 [class.ctor] paragraphs 5-6 as follows:

  4. A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (9.5 [dcl.fct.def]). An implicitly-declared default constructor is an inline public member of its class. A default constructor is trivial if it is not user-provided (9.5 [dcl.fct.def]) and if:

    • its class has no virtual functions (11.7.3 [class.virtual]) and no virtual base classes (11.7.2 [class.mi]), 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.

    An implicitly-declared defaulted default constructor for class X is defined as deleted if:

    • X is a union-like class that has a variant member with a non-trivial default constructor,

    • any non-static data member is of reference type,

    • any non-static data member of const-qualified type (or array thereof) does not have a user-provided default constructor, or

    • any non-static data member or direct or virtual base class has class type M (or array thereof) and M has no default constructor, or if overload resolution (12.2 [over.match]) as applied to M's default constructor, results in an ambiguity or a function that is deleted or inaccessible from the implicitly-declared default constructor.

    A default constructor is trivial if it is neither user-provided nor deleted and if:

    • its class has no virtual functions (11.7.3 [class.virtual]) and no virtual base classes (11.7.2 [class.mi]), 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.

    Otherwise, the default constructor is non-trivial.

    A non-user-provided default constructor for a class that is defaulted and not deleted is implicitly defined when it is used (6.3 [basic.def.odr]) to create an object of its class type (6.7.2 [intro.object]), or when it is explicitly defaulted after its first declaration. The implicitly-defined or explicitly-defaulted default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (11.9.3 [class.base.init]) and an empty compound-statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr constructor (9.2.6 [dcl.constexpr]), the implicitly-defined default constructor is constexpr. Before the non-user-provided defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members shall have been implicitly defined. [Note: an implicitly-declared default constructor has an exception-specification (14.5 [except.spec]). An explicitly-defaulted definition has no implicit exception-specification. —end note]

  5. Change 11.4.7 [class.dtor] paragraphs 3-4 as follows:

  6. If a class has no user-declared destructor, a destructor is declared implicitly declared as defaulted (9.5 [dcl.fct.def]). An implicitly-declared destructor is an inline public member of its class. If the class is a union-like class that has a variant member with a non-trivial destructor, an implicitly-declared destructor is defined as deleted (9.5 [dcl.fct.def]). A destructor is trivial if it is not user-provided and if:

    • the destructor is not virtual,

    • all of the direct base classes of its class have trivial destructors, and

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

    An implicitly-declared defaulted destructor for a class X is defined as deleted if:

    • X is a union-like class that has a variant member with a non-trivial destructor,

    • any of the non-static data members has class type M (or array thereof) and M has an a deleted destructor or a destructor that is inaccessible from the implicitly-declared destructor, or

    • any direct or virtual base class has a deleted destructor or a destructor that is inaccessible from the implicitly-declared destructor.

    A destructor is trivial if it is neither user-provided nor deleted and if:

    • the destructor is not virtual,

    • all of the direct base classes of its class have trivial destructors, and

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

    A non-user-provided destructor that is defaulted and not defined as deleted is implicitly defined when it is used to destroy an object of its class type (6.7.5 [basic.stc]), or when it is explicitly defaulted after its first declaration. A program is ill-formed if the class for which a destructor is implicitly defined or explicitly defaulted has:

    • a non-static data member of class type (or array thereof) with an inaccessible destructor, or

    • a base class with an inaccessible destructor.

    Before the non-user-provided defaulted destructor for a class is implicitly defined, all the non-user-defined non-user-provided destructors for its base classes and its non-static data members shall have been implicitly defined. [Note: an implicitly-declared destructor has an exception-specification (14.5 [except.spec]). An explictly defaulted definition has no implicit exception-specification. —end note]

  7. Change _N4750_.15.8 [class.copy] paragraphs 4-9 as follows:

  8. If the class definition does not explicitly declare a copy constructor, one is declared implicitly implicitly declared as defaulted (9.5 [dcl.fct.def]). Thus...

    ...An implicitly-declared copy constructor is an inline public member of its class. An implicitly-declared defaulted copy constructor for a class X is defined as deleted if X has: ...

    A copy constructor for class X is trivial trivial if it is not neither user-provided nor deleted (9.5 [dcl.fct.def]) and if...

    A non-user-provided copy constructor that is defaulted and not defined as deleted is implicitly defined if it is used to initialize an object of its class type from a copy of an object of its class type or of a class type derived from its class type116, or when it is explicitly defaulted after its first declaration. [Note: the copy constructor is implicitly defined even if the implementation elided its use (6.7.7 [class.temporary]). —end note]

    Before the non-user-provided defaulted copy constructor for a class is implicitly defined, all non-user-provided copy constructors...

    The implicitly-defined or explicitly-defaulted copy constructor for a non-union class X performs...

    The implicitly-defined or explicitly-defaulted copy constructor for a union X copies the object representation (6.8 [basic.types]) of X.

  9. Change _N4750_.15.8 [class.copy] paragraphs 11-15 as follows:

  10. If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly implicitly declared as defaulted (9.5 [dcl.fct.def])...

    ...An implicitly-declared defaulted copy assignment operator for class X is defined as deleted if X has:...

    A copy assignment operator for class X is trivial if it is not neither user-provided nor deleted and if...

    A non-user-provided copy assignment operator that is defaulted and not defined as deleted is implicitly defined when an object of its class type is assigned a value of its class type or a value of a class type derived from its class type, or when it is explicitly defaulted after its first declaration.

    Before the non-user-provided defaulted copy assignment operator for a class is implicitly defined...

    The implicitly-defined or explicitly-defaulted copy assignment operator for a non-union class X performs...

    It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined or explicitly-defaulted copy assignment operator. [Example:...

    The implicitly-defined or explicitly-defaulted copy assignment operator for a union X copies the object representation (6.8 [basic.types]) of X.

Date: 2009-07-15.00:00:00

Notes from the July, 2009 meeting:

The July, 2009 resolution of issue 906 addresses the example above (with an inaccessible defaulted destructor): a defaulted special member function can only have non-public access if the defaulted definition is outside the class, making it non-trivial. The example as written above would be ill-formed.

Date: 2009-05-15.00:00:00

Additional notes (May, 2009):

Consider the following example:

    struct Base {
      private:
        ~Base() = default;
    };

    struct Derived: Base {
    };

The implicitly-declared destructor of Derived is defined as deleted because Base::~Base() is inaccessible, but it fulfills the requirements for being trivial. Presumably the Base destructor should be non-trivial, either by directly specifying that it is non-trivial or by specifying that it is user-provided. An alternative would be to make it ill-formed to attempt to declare a defaulted non-public special member function.

Any changes to the definition of triviality should be checked against Clause 11 [class] paragraph 6 for any changes needed there to accommodate the new definitions.

Date: 2008-06-15.00:00:00

Notes from the June, 2008 meeting:

It appears that this issue will be resolved by the concepts proposal directly. The issue is in “review” status to check if that is indeed the case in the final version of the proposal.

Date: 2008-02-15.00:00:00

Notes from the February, 2008 meeting:

Deleted special member functions are also not trivial. Resolution of this issue should be coordinated with the concepts proposal.

Date: 2020-12-15.00:00:00

Should the following class have a trivial copy assignment operator?

    struct A {
        int& m;
        A();
        A(const A&);
    };

_N4750_.15.8 [class.copy] paragraph 11 does not mention whether the presence of reference members (or cv-qualifiers, etc.) should affect triviality. Should it?

One reason why this matters is that implementations have to make the builtin type trait operator __has_trivial_default_ctor(T) work so that they can support the type trait template std::has_trivial_default_constructor.

Assuming the answer is “yes,” it looks like we probably need similar wording for trivial default and trivial copy ctors.

History
Date User Action Args
2010-03-29 00:00:00adminsetmessages: + msg2720
2010-03-29 00:00:00adminsetstatus: ready -> cd2
2009-11-08 00:00:00adminsetmessages: + msg2367
2009-11-08 00:00:00adminsetstatus: drafting -> ready
2009-08-03 00:00:00adminsetmessages: + msg2200
2009-06-19 00:00:00adminsetmessages: + msg2046
2009-03-23 00:00:00adminsetstatus: review -> drafting
2008-06-29 00:00:00adminsetmessages: + msg1687
2008-06-29 00:00:00adminsetstatus: open -> review
2008-03-17 00:00:00adminsetmessages: + msg1610
2007-12-14 00:00:00admincreate