new syntax for cleanup (was Re: destructors order not guaranteed?)

Bjorn Pettersen bjorn at roguewave.com
Mon Nov 6 15:51:57 EST 2000


Alex Martelli wrote:
> 
> "Bjorn Pettersen" <bjorn at roguewave.com> writes:
>     [snip]
> > > If a function called in a C++ destructor throws, and the
> > > exception exits from the destructor, what happens next is
> > > pandemonium.  "A destructor must not throw" is not written
>     [snip]
> > I'm not sure I understand what you're saying here... There are two
> > situations that are possible here in C++:
> >
> >  - an exception is thrown in a normal context (e.g. at the end of
> >    a scope). Such an exception will be caught by the nearest
> >    enclosing handler.
> >  - an exception is thrown from a destructor during stack
> >    unwinding (i.e. another exception happened). In this case
> >    std::terminate() is called.
> >
> > Both cases are well defined and I would hardly call the results
> > "pandemonium"...?
> 
> Sorry for being a little colorful here!-)  But, hey, you gotta
> expect that from us Italians.  "Obvious" context: suppose
> your destructors are doing _important_ stuff, stuff that MUST
> be done -- what one would do in a "finally" clause in Java
> or Python.  For example, erasing big files, intended to be
> temporary, that would otherwise stay around, clog the disk,
> and bring a crucial server to its knees, right?
> 
> It's not a problem that C++ does not have a 'finally' clause,
> right?  As long as you take care to delegate the 'finally' stuff
> to destructors of auto-storage class objects, you can rely on
> that crucial finalization stuff getting executed, right...?
> 
> Wrong.  You can't, *unless* you trust *every* destructor
> never to throw (and let escape) any exceptions.
[snip]

It seems to me you're talking about when things are going terribly
wrong, and I can't see how this case is any different from an expression
in a finally clause raising an exception:

  db = None
  try:
     db = OpenDatabase()
     ...
  finally:
     foo()
     if db:
        del db # presumably calls db.close()
     bar()

vs.

  {
    MyDB db = OpenDataBase();
    ...
    foo();
    bar();
  }

If foo() throws/raises an exception, db's destructor will be called in
the C++ version, but not in the Python version, and in C++ bar() will be
called even if db's destructor throws (but not if foo() throws).

I like Python's simplicity, but I do think C++' exception handling and
recovery is more completely thought out...

-- bjorn




More information about the Python-list mailing list