This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-06
[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):
Change 9.5 [dcl.fct.def] paragraph 9 as follows:
...Only special member functions may be explicitly defaulted. Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shalldefine them as if they hadprovide 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:...
Change 11.4.5 [class.ctor] paragraphs 5-6 as follows:
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.A
n implicitly-declareddefaulted 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-provideddefault constructorfor a classthat 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-definedor explicitly-defaulteddefault 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 thenon-user-provideddefaulted 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]
Change 11.4.7 [class.dtor] paragraphs 3-4 as follows:
If a class has no user-declared destructor, a destructor is
declaredimplicitly 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.A
n implicitly-declareddefaulted 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
ana deleted destructor or a destructor that is inaccessible from the implicitly-declared destructor, orany 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-provideddestructor 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-provideddefaulted destructor for a class is implicitly defined, all thenon-user-definednon-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]
Change 11.4.5.3 [class.copy.ctor] paragraphs 4-9 as follows:
If the class definition does not explicitly declare a copy constructor, one is
declared implicitlyimplicitly declared as defaulted (9.5 [dcl.fct.def]). Thus......An implicitly-declared copy constructor is an inline public member of its class. A
n implicitly-declareddefaulted copy constructor for a class X is defined as deleted if X has: ...A copy constructor for class X is
trivialtrivial if it isnotneither user-provided nor deleted(9.5 [dcl.fct.def])and if...A
non-user-providedcopy 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-provideddefaulted copy constructor for a class is implicitly defined, all non-user-provided copy constructors...The implicitly-defined
or explicitly-defaultedcopy constructor for a non-union class X performs...The implicitly-defined
or explicitly-defaultedcopy constructor for a union X copies the object representation (6.8 [basic.types]) of X.
Change 11.4.5.3 [class.copy.ctor] paragraphs 11-15 as follows:
If the class definition does not explicitly declare a copy assignment operator, one is
declared implicitlyimplicitly declared as defaulted (9.5 [dcl.fct.def])......A
n implicitly-declareddefaulted 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
notneither user-provided nor deleted and if...A
non-user-providedcopy 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-provideddefaulted copy assignment operator for a class is implicitly defined...The implicitly-defined
or explicitly-defaultedcopy 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-defaultedcopy assignment operator. [Example:...The implicitly-defined
or explicitly-defaultedcopy assignment operator for a union X copies the object representation (6.8 [basic.types]) of X.