This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


667. Trivial special member functions that cannot be implicitly defined

Section: 11.4.5.3  [class.copy.ctor]     Status: CD2     Submitter: James Widman     Date: 14 December 2007

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

Should the following class have a trivial copy assignment operator?

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

11.4.5.3 [class.copy.ctor] 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.

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.

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.

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.

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.

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], 11.4.5.3 [class.copy.ctor]), 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:

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

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

    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:

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

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

    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:

    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 11.4.5.3 [class.copy.ctor] 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 11.4.5.3 [class.copy.ctor] 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.