On 25 November 2010 12:01, Duncan Sands <baldrick at free.fr> wrote:> I see what you are saying now. Unfortunately optimizations such as > inlining can result in code ending up in cleanup landing pads.This is the part that escapes me... but I haven't spent too much time thinking about inlining EH information yet.> OK :) Essentially what happens is as follows: when running destructors > when exiting a scope (which may be a nested scope), if a destructor throws > an exception then any remaining destructors are first run, then the > Program_Error exception is thrown at the point of the scope exit. This > may be caught by an enclosing handler.That's a neat model. What happens if two (or more) exceptions are thrown while you're cleaning up another? For instance, if A's destructor also throws an exception? A's exception was not thrown while processing B's exception (but while cleaning up *before* processing it), so it's not a nested exception, but an "aside" exception... It makes my head hurt... I think Stroustroup didn't want to think about that, too... :D cheers, --renato
Hi Renato,>> OK :) Essentially what happens is as follows: when running destructors >> when exiting a scope (which may be a nested scope), if a destructor throws >> an exception then any remaining destructors are first run, then the >> Program_Error exception is thrown at the point of the scope exit. This >> may be caught by an enclosing handler. > > That's a neat model. > > What happens if two (or more) exceptions are thrown while you're > cleaning up another? For instance, if A's destructor also throws an > exception?in that case, any remaining destructors are run and Program_Error is thrown at the point of scope exit :) In short, all destructors are run, and if any throw exceptions then that fact is noted somewhere (and the exception is not allowed to propagate) and once all destructors have had a chance to run then one instance of Program_Error is thrown at the point of scope exit. Note that the fact that the exception is thrown not at the place where a particular destructor went wrong but at the end of the scope means that exactly the same exception is thrown no matter which (or how many) destructors barfed with an exception. If you had to throw the exception at the particular point in the destructor's code where the failure happened then you would be in trouble if multiple destructors failed (at which spot would you throw the exception?).> A's exception was not thrown while processing B's exception (but while > cleaning up *before* processing it), so it's not a nested exception, > but an "aside" exception... > > It makes my head hurt... I think Stroustroup didn't want to think > about that, too... :DActually it's pretty simple, see above. Ciao, Duncan.
On 25 November 2010 13:31, Duncan Sands <baldrick at free.fr> wrote:> In short, all destructors are run, and if any > throw > exceptions then that fact is noted somewhere (and the exception is not > allowed > to propagate) and once all destructors have had a chance to run then one > instance of Program_Error is thrown at the point of scope exit.I see, like keeping the exceptions in a queue as they happen and deal with each one in order, until the queue is empty. It's harder to print stack-traces to the user, but this discussion is becoming off-topic. ;) Anyway, thanks for the explanation! cheers, --renato