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

2024-10-26


1658. Deleted default constructor for abstract class via destructor

Section: 11.4.5  [class.ctor]     Status: C++14     Submitter: Richard Smith     Date: 2013-08-26

[Moved to DR at the February, 2014 meeting.]

While reviewing the resolution of issue 1611, it was noticed that the final bullet of 11.4.5 [class.ctor] paragraph 4 has a similar issue:

...A defaulted default constructor for class X is defined as deleted if:

Presumably destructors for virtual bases of abstract classes should not be considered in making this determination.

A question was also raised regarding whether odr-use is correctly defined for destructors of virtual bases of abstract classes. 6.3 [basic.def.odr] paragraph 3 simply refers to 11.4.7 [class.dtor], where the relevant passage (paragraph 8) reads,

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X's direct non-variant non-static data members, the destructors for X's direct base classes and, if X is the type of the most derived class (11.9.3 [class.base.init]), its destructor calls the destructors for X's virtual base classes.

It could be argued, particularly in light of the reference to 11.9.3 [class.base.init], that this is clear enough that the destructor for an abstract class does not invoke destructors for its virtual bases, but a note to that effect might be helpful.

Proposed resolution (November, 2013):

  1. Add the following as a new paragraph at the end of 11.4.4 [special]:

  2. For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract (11.7.4 [class.abstract]), its virtual base classes are called its potentially constructed subobjects.
  3. Change 11.4.5 [class.ctor] paragraph 4 as follows:

  4. ...A defaulted default constructor for class X is defined as deleted if:

  5. Change 11.4.7 [class.dtor] paragraph 5 as follows:

  6. A defaulted destructor for a class X is defined as deleted if:

  7. Change 11.9.3 [class.base.init] paragraph 8 as follows:

  8. In a non-delegating constructor, if a given non-static data member or base class potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (11.7.4 [class.abstract]), then...
  9. Change 11.9.3 [class.base.init] paragraph 10 as follows:

  10. In a non-delegating constructor, the destructor for each direct or virtual base class and for each non-static data member potentially constructed subobject of class type is potentially invoked (11.4.7 [class.dtor]). [Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (14.3 [except.ctor]). —end note]
  11. Change 11.4.5.3 [class.copy.ctor] paragraph 8, replacing the bulleted list with a single sentence, as follows:

  12. The implicitly-declared copy constructor for a class X will have the form

    if each potentially constructed subobject

    Otherwise...

  13. Change 11.4.5.3 [class.copy.ctor] paragraph 11 as follows:

  14. An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move constructor for a class X is defined as deleted (9.5.3 [dcl.fct.def.delete]) if X has:

  15. Change 11.4.5.3 [class.copy.ctor] paragraph 14 as follows:

  16. Before the defaulted copy/move constructor for a class is implicitly defined, all non-user-provided copy/move constructors for its direct and virtual base classes and its non-static data members potentially constructed subobjects shall have been implicitly defined. [Note: An implicitly-declared copy/move constructor has an exception-specification (14.5 [except.spec]). —end note]
  17. Change 11.4.5.3 [class.copy.ctor] paragraph 23 as follows:

  18. A defaulted copy/move assignment operator for class X is defined as deleted if X has:

This resolution also resolves issue 1611.