Created on2013-09-24.00:00:00 last changed109 months ago
[Moved to DR at the November, 2014 meeting.]
Proposed resolution (June, 2014):
Change all of 14.3 [except.ctor], reparagraphingas follows:
As control passes from the point where an exception is thrown toa handler, destructors are invokedby a process, specified inthis section, calledstack unwinding. If a destructordirectly invoked by stack unwinding exits with an exception,std::terminate is called (14.6.2 [except.terminate]).[Note: Consequently, destructors should generally catchexceptions and not let them propagate out of the destructor.—end note]
The destructor is invokedfor
all automatic objectseach automaticobject of class type constructed since the try blockwas entered. The automatic objects are destroyed in the reverseorder of the completion of their construction.
AnFor an objectof classtype of any storage duration whose initialization ordestruction is terminated by an exceptionwill havedestructors executed, the destructor is invokedforalleach ofitstheobject's fully constructed subobjects (excluding thevariant members of a union-like class), that is,forsubobjectseach subobject for which theprincipal constructor (11.9.3 [class.base.init]) has completedexecution and the destructor has not yet begunexecution.The subobjects are destroyed in the reverse orderof the completion of their construction. Such destruction issequenced before entering a handler of thefunction-try-blockof the constructor or destructor, if any.Similarly, if the non-delegating constructor for anobject has completed execution and a delegating constructor forthat object exits with an exception, the object's destructor
willbeis invoked.Such destruction is sequencedbefore entering a handler of thefunction-try-block of adelegating constructor for that object, if any.[Note: If the object wasallocated
inby anew-expression(7.6.2.8 [expr.new]), the matchingdeallocation function (6.8.6.5.3 [basic.stc.dynamic.deallocation],7.6.2.8 [expr.new], 11.4.11 [class.free]), if any,is called to free the storage occupied by the object.—end note]
The process of calling destructors for automatic objectsconstructed on the path from a try block to the point where anexception is thrown is called “stack unwinding.” If adestructor called during stack unwinding exits with an exception,std::terminate is called(14.6.2 [except.terminate]). [Note: So destructorsshould generally catch exceptions and not let them propagate outof the destructor. —end note]
Delete 14.4 [except.handle] paragraph 11:
The fully constructed base classes and members of an object shallbe destroyed before entering the handler ofafunction-try-block of a constructor for thatobject. Similarly, if a delegating constructor for an objectexits with an exception after the non-delegating constructor forthat object has completed execution, the object's destructorshall be executed before entering the handler ofafunction-try-block of a constructor for that object. Thebase classes and non-variant members of an object shall bedestroyed before entering the handler ofafunction-try-block of a destructor for that object(11.4.7 [class.dtor]).
This resolution also resolvesissue 1807.
Notes from the September, 2013 meeting:
Although the Canadian NB comment principally was a request to reconsiderthe resolution ofissue 1424, which CWG decidedto retain, the comment also raised the question above, which CWG feltmerited its own issue.
The current wording of 14.6.2 [except.terminate] paragraph 2affords implementations a significant degree of freedom when exceptionhandling results in a call tostd::terminate:
In the situation where no matching handler is found, it isimplementation-defined whether or not the stack is unwound beforestd::terminate() is called. In the situation where the search fora handler (14.4 [except.handle]) encounters the outermost block of afunction with anoexcept-specification that does not allow theexception (14.5 [except.spec]), it is implementation-defined whetherthe stack is unwound, unwound partially, or not unwound at all beforestd::terminate() is called. In all other situations, the stackshall not be unwound before std::terminate() is called.
This contrasts with the treatment of subobjects and objects constructedvia delegating constructos in 14.3 [except.ctor] paragraph 2:
An object of any storage duration whose initialization or destruction isterminated by an exception will have destructors executed for all of itsfully constructed subobjects (excluding the variant members of a union-likeclass), that is, for subobjects for which the principal constructor(11.9.3 [class.base.init]) has completed execution and the destructorhas not yet begun execution. Similarly, if the non-delegating constructorfor an object has completed execution and a delegating constructor for thatobject exits with an exception, the object's destructor will be invoked.
Here the destructors must be called. It would be helpful if theserequirements were harmonized.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2017-02-06 00:00:00 | admin | set | status: drwp -> cd4 |
| 2015-05-25 00:00:00 | admin | set | status: dr -> drwp |
| 2015-04-13 00:00:00 | admin | set | messages: +msg5420 |
| 2014-11-24 00:00:00 | admin | set | status: tentatively ready -> dr |
| 2014-07-07 00:00:00 | admin | set | messages: +msg5082 |
| 2014-07-07 00:00:00 | admin | set | status: drafting -> tentatively ready |
| 2014-03-03 00:00:00 | admin | set | status: open -> drafting |
| 2013-10-14 00:00:00 | admin | set | messages: +msg4673 |
| 2013-09-24 00:00:00 | admin | create | |