current_exception()
's interaction with throwing copy ctorsSection: 17.9.7 [propagation] Status: CD1 Submitter: Stephan T. Lavavej Opened: 2008-03-26 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [propagation].
View all issues with CD1 status.
Discussion:
As of N2521, the Working Paper appears to be silent about what
current_exception()
should do if it tries to copy the currently handled
exception and its copy constructor throws. 17.9.7 [propagation]/7 says "If the
function needs to allocate memory and the attempt fails, it returns an
exception_ptr
object that refers to an instance of bad_alloc
.", but
doesn't say anything about what should happen if memory allocation
succeeds but the actual copying fails.
I see three alternatives: (1) return an exception_ptr
object that refers
to an instance of some fixed exception type, (2) return an exception_ptr
object that refers to an instance of the copy ctor's thrown exception
(but if that has a throwing copy ctor, an infinite loop can occur), or
(3) call terminate()
.
I believe that terminate()
is the most reasonable course of action, but
before we go implement that, I wanted to raise this issue.
[ Peter's summary: ]
The current practice is to not have throwing copy constructors in exception classes, because this can lead to
terminate()
as described in 14.6.2 [except.terminate]. Thus callingterminate()
in this situation seems consistent and does not introduce any new problems.However, the resolution of core issue 475 may relax this requirement:
The CWG agreed with the position that
std::uncaught_exception()
should returnfalse
during the copy to the exception object and thatstd::terminate()
should not be called if that constructor exits with an exception.Since throwing copy constructors will no longer call
terminate()
, option (3) doesn't seem reasonable as it is deemed too drastic a response in a recoverable situation.Option (2) cannot be adopted by itself, because a potential infinite recursion will need to be terminated by one of the other options.
Proposed resolution:
Add the following paragraph after 17.9.7 [propagation]/7:
Returns (continued): If the attempt to copy the current exception object throws an exception, the function returns an
exception_ptr
that refers to the thrown exception or, if this is not possible, to an instance ofbad_exception
.[Note: The copy constructor of the thrown exception may also fail, so the implementation is allowed to substitute a
bad_exception
to avoid infinite recursion. -- end note.]
Rationale:
[ San Francisco: ]
Pete: there may be an implied assumption in the proposed wording that current_exception() copies the existing exception object; the implementation may not actually do that.
Pete will make the required editorial tweaks to rectify this.