Title
Destroying the returned object when a destructor throws
Status
cd4
Section
7.6.1.3 [expr.call]
Submitter
Richard Smith

Created on 2015-09-28.00:00:00 last changed 94 months ago

Messages

Date: 2016-02-15.00:00:00

Proposed resolution (February, 2016):

Change 14.3 [except.ctor] paragraph 2 as follows:

The destructor is invoked for each automatic object of class type constructed, but not yet destroyed, since the try block was entered. If an exception is thrown during the destruction of temporaries or local variables for a return statement (8.7.4 [stmt.return]), the destructor for the returned object (if any) is also invoked. The automatic objects are destroyed in the reverse order of the completion of their construction. [Example:

  struct A { };

  struct Y { ~Y() noexcept(false) { throw 0; } };

  A f() {
    try {
      A a;
      Y y;
      A b;
      return {};   // #1
    } catch (...) {
    }
    return {};     // #2
  }

At #1, the returned object of type A is constructed. Then, the local variable b is destroyed (8.7 [stmt.jump]). Next, the local variable y is destroyed, causing stack unwinding, resulting in the destruction of the returned object, followed by the destruction of the local variable a. Finally, the returned object is constructed again at #2. —end example]

Date: 2016-02-15.00:00:00

[Adopted at the February, 2016 meeting.]

Consider the following example:

  #include <stdio.h>

  struct X {
    X() { puts("X()"); }
    X(const X&) { puts("X(const X&)"); }
    ~X() { puts("~X()"); }
  };

  struct Y { ~Y() noexcept(false) { throw 0; } };

  X f() {
    try {
      Y y;
      return {};
    } catch (...) {
    }
    return {};
  }

  int main() {
    f();
  }

Current implementations print X() twice but ~X() only once. That is obviously wrong, but it is not clear that the current wording covers this case.

History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: tentatively ready -> cd4
2016-02-15 00:00:00adminsetmessages: + msg5696
2016-02-15 00:00:00adminsetstatus: drafting -> tentatively ready
2015-09-28 00:00:00admincreate