Article View: comp.std.c++
Article #2692Exceptions and dtors
From: Herb Sutter
Date: Wed, 22 Nov 1995 04:46
Date: Wed, 22 Nov 1995 04:46
101 lines
6054 bytes
6054 bytes
PROBLEM: Basic Inconsistency (Ctors and Dtors and Exceptions) It's occurred to me that the basic inconsistency in current exception rules still hasn't been resolved: - On one hand, exceptions are (among other things) meant to be a way to provide error handling mechanisms for ctors, since ctors cannot return error values. This is not only legitimate, but elegant and necessary. - On the other hand, under current rules we dare not use exceptions to provide error handling mechnisms for dtors, even though these share the same problem with ctors (both cannot return error values). Briefly, this is because the dtor might be called during stack unwinding while another exception is already active, and under the current rules any further exceptions thrown in that state abort the program. I'm not convinced that last 'must abort' rule is necessary. It seems clear to me that the ctor and dtor needs are quite similar and that excluding one from using exceptions as error returns (not by language rule, but by making it so dangerous as to be shunned) is most unfortunate... particularly since the dangerous case is rare and the vast majority of the time dtor exceptions would be fine even now. PROPOSAL: Allow Multiple Simultaneous Exceptions Consider a change in the rule for exceptions thrown during stack unwinding (note: this proposal doesn't affect any other part of the standard, it doesn't impose burden on code not making use of it, etc.). Suppose that an exception is active and the stack is being unwound, and while one dtor is being processed it throws its own exception... instead of arbitrarily halting the program, we simply add the new exception to the existing list of active exceptions; the dtor throwing the new exception is naturally exited (just as a ctor that throws is exited), but destruction continues as usual... the program first calls dtors for member objects, then the base dtors, etc. Informally, the program continues stack unwinding as before, except that now two exceptions are known to be active and the dtor that threw the second exception naturally didn't complete because it threw. Basically all that's now needed is a rule for when to stop. There seem to be two main possibilities. In both, we keep unwinding (and possibly adding new exceptions as we go) until a handler for any one of the active exceptions is found (if there are two exceptions of the same type, use some rule, e.g. "first thrown first handled", to define which gets handled first). Then, either: a) discard all other active exceptions and continue execution from the handler for the first matched exception (this may allow other errors to be left unhandled, but there may be valid arguments in favour of this, e.g. 'but that's the first handler that claimed it could do something about this tragedy with possibly multiple symptoms [exceptions], and since the exceptions are likely related this handler is probably the one we should want since it does in fact know how to handle a symptom'); or b) invoke the matching handler, remove the handled exception from the list, then continue unwinding (adding any new exceptions if they're thrown and invoking handlers to get rid of active exceptions as valid handlers are encountered) until we've handled the last active exception, then continue progam control flow from after that handler (I like this better in some ways and there may be arguments for this as well, e.g. 'this way all our individual errors/symptoms get specifically addressed', but (a) also has its share of elegance and arguments). ADVANTAGES: This scheme allows exceptions to be properly and safely used in dtors. By far the majority of the time dtors aren't being called in the context of an exception anyway, and so the current rules impose undue hardship by making dtor exceptions so unsafe as to be unusable (because even one at a bad time could crash the program), when in fact even now dtor exceptions are already safe the vast majority of the time. The rules just make the 'rare' case so incredibly dangerous that it can't be risked and must be avoided completely. In so doing, the current rules create an inelegant -- and, worse, inconsistent -- partial solution that addresses half the problem (errors in ctors, for ctors can't return values) while leaving the identical other half unaddressed (errors in dtors, for they have the same restrictions as ctors and the problem is basically no different). SUMMARY: It seems clear to me that the main question with the above is probably: 'When do we stop unwinding?' That is, do we stop as soon as we can handle any of the active exceptions? when we've handled all of them? or something else? Personally, I think that either of the first two answers would probably be fine and so complicated rules should be unnecessary, but only further discussion can prove or disprove that 'I think that...'. :-) Comments and discussion welcome. Herb ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Herb Sutter 2228 Urwin, Ste 102 voice (416) 618-0184 Connected Object Solutions Oakville ON Canada L6L 2T2 fax (905) 847-6019 --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID:
<48u966$ak9@steel.interlog.com>Path:
arc1-ca.pugleaf.net!in1.uu.net!bounce-backShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!in1.uu.net!bounce-back Date: 22 Nov 95 04:46:46 GMT Approved: fjh@cs.mu.oz.au From: herbs@interlog.com (Herb Sutter) Newsgroups: comp.std.c++ Subject: Exceptions and dtors X-Original-Date: Wed, 22 Nov 95 04:34:21 GMT Organization: Connected Object Solutions (div of Daystar Software Systems Design Inc.) Message-ID: <48u966$ak9@steel.interlog.com> X-Newsreader: News Xpress Version 1.0 Beta #4 X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMLKrZuEDnX0m9pzZAQGBZwF+P49U6P/aSrhXaSF8ZJwNqibEhH1wA/eD /fppUpM2wEyICLWd7ypp4lXzBrx/voPg =SAME