Date
2007-09-15.00:00:00
Message id
1532

Content

Additional notes (September, 2007):

Although this issue deals primarily with when std::uncaught_exception() begins to return true, the specification of when it begins to return false is also problematic. There are two parallel sections that define the meaning of std::uncaught_exception() and each has a different problem. _N5001_.14.6.3 [except.uncaught] reads,

The function std::uncaught_exception() returns true after completing evaluation of the object to be thrown until completing the initialization of the exception-declaration in the matching handler (_N4140_.18.8.4 [uncaught]).

The problem here is that whether an exception is considered caught (the underlying condition tested by the function) is here presented in terms of having initialized the exception-declaration, while in other places it is specified by having an active handler for the exception, e.g., 14.2 [except.throw] paragraph 6:

An exception is considered caught when a handler for that exception becomes active (14.4 [except.handle]).

This distinction is important because of 14.4 [except.handle] paragraph 3:

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. —end note] Also, an implicit handler is considered active when std::terminate() or std::unexpected() is entered due to a throw.

Note that there is no exception-declaration to be initialized for the std::terminate() and std::unexpected() cases; nevertheless, according to _N4140_.18.8.4 [uncaught], std::uncaught_exception() is supposed to return false when one of those two functions is entered.

The specification in _N4140_.18.8.4 [uncaught] is not well phrased, however, and is open to misinterpretation. It reads,

Returns: true after completing evaluation of a throw-expression until either completing initialization of the exception-declaration in the matching handler or entering unexpected() due to the throw; or after entering terminate() for any reason other than an explicit call to terminate().

The problem here is lack of parallelism: does “after entering terminate” refer to the condition for returning true or false? This would be better phrased along the lines of

Returns: true after completing evaluation of a throw-expression until a handler for the exception becomes active (14.4 [except.handle]).