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


208. Rethrowing exceptions in nested handlers

Section: 14.2  [except.throw]     Status: CD1     Submitter: Bill Wade     Date: 28 Feb 2000

[Moved to DR at 4/01 meeting.]

Paragraph 7 of 14.2 [except.throw] discusses which exception is thrown by a throw-expression with no operand.

May an expression which has been "finished" (paragraph 7) by an inner catch block be rethrown by an outer catch block?

    catch(...)    // Catch the original exception
    {
      try{ throw; }    // rethrow it at an inner level
                       // (in reality this is probably
                       // inside a function)
      catch (...)
      {
      }   // Here, an exception (the original object)
          // is "finished" according to 15.1p7 wording

      // 15.1p7 says that only an unfinished exception
      // may be rethrown.
      throw;    // Can we throw it again anyway?  It is
                // certainly still alive (15.1p4).
    }

I believe this is ok, since the paragraph says that the exception is finished when the "corresponding" catch clause exits. However since we have two clauses, and only one exception, it would seem that the one exception gets "finished" twice.

Proposed resolution (04/01):

  1. In 14.2 [except.throw] paragraph 4, change

    When the last handler being executed for the exception exits by any means other than throw; ...
    to
    When the last remaining active handler for the exception exits by any means other than throw; ...

  2. In 14.2 [except.throw] paragraph 6, change

    A throw-expression with no operand rethrows the exception being handled.
    to
    A throw-expression with no operand rethrows the currently handled exception (14.4 [except.handle]).

  3. Delete 14.2 [except.throw] paragraph 7.

  4. Add the following before 14.2 [except.throw] paragraph 6:

    An exception is considered caught when a handler for that exception becomes active (14.4 [except.handle]). [Note: an exception can have active handlers and still be considered uncaught if it is rethrown.]

  5. Change 14.4 [except.handle] paragraph 8 from

    An exception is considered handled upon entry to a handler. [Note: the stack will have been unwound at that point.]
    to

    A handler is considered active when initialization is complete for the formal parameter (if any) of the catch clause. [Note: the stack will have been unwound at that point.] Also, an implicit handler is considered active when std::terminate() or std::unexpected() is entered due to a throw. A handler is no longer considered active when the catch clause exits or when std::unexpected() exits after being entered due to a throw.

    The exception with the most recently activated handler that is still active is called the currently handled exception.

  6. In 14.4 [except.handle] paragraph 16, change "exception being handled" to "currently handled exception."