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

2024-12-19


2336. Destructor characteristics vs potentially-constructed subobjects

Section: 14.5  [except.spec]     Status: CD5     Submitter: Nathan Sidwell     Date: 2017-02-28

[Accepted as a DR at the February, 2019 meeting.]

According to 14.5 [except.spec] paragraph 8,

The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier, is potentially-throwing if and only if any of the destructors for any of its potentially constructed subojects is potentially throwing.

11.4.4 [special] paragraph 5 defines “potentially constructed subobjects” as follows:

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.

This leads to the following problem:

  class V {
  public:
    virtual ~V() noexcept(false);
  };

  class B : virtual V {
    virtual void foo () = 0;
    // implicitly defined virtual ~B () noexcept(true);
  };

  class D : B {
    virtual void foo ();
    // implicitly defined virtual ~D () noexcept(false);
  };

Here, D::~D() is throwing but overrides the non-throwing B::~B().

There are similar problems with the deletedness of destructors per 11.4.7 [class.dtor] paragraph 5, which also only considers potentially constructed subobjects.

Proposed resolution (November, 2018):

Change 14.5 [except.spec] paragraph 8 as follows:

The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier, is potentially-throwing if and only if any of the destructors for any of its potentially constructed subobjects is potentially throwing potentially-throwing or the destructor is virtual and the destructor of any virtual base class is potentially-throwing.