Re: need argument for try catch blocks
"Fred Zwarts" <F.Zwarts@KVI.nl>
One can always call anything from within a destructor. One
then just has to wrap everything with ?try? and ?catch?, so
that exceptions /do not leave/ the destructor.
This works, of course, only if the destructor knows how to handle the
exception.
But what should the destructor do with unknown exceptions?
Ignoring them will cause the program to continue in a undefined state.
What undefined state? Normally throw happens related to particular object.
With basic guarantee the caller will no the object in question has not
reached the known state. So mey do some action. For dtors, the object will
be gone so that does not apply. Do not confuse unknown state with undefined
behavior.
Is that better then UB?
Definietely.
So, just wrapping a destructor code in a try { ...catch (...) {}is not a
real solution.
Still better than throwing for the general case. As if that happens, the
dtor chain is stopped right there. Is a member object's dtor throws the
other members in the same complete objects will not be called. If dtor
halfway in the array throws, dtors for the rest of the array are not called.
So throwing you disrupt the symmetry and will cause leaks unless very lucky.
For example, if memory is properly managed, a delete should not throw an
exception.
If it does, it may be an indication of memory corruption.
If memory is detectably corrupt then you shall not throw but halt in tracks.
Throw is NOT for handling program bugs but for recoverable runtime
conditions.
Should the destructor ignore it and let the program continue,
or is it better to let the exception leave the destructor, so that the
program will terminate,
or should it immediately call terminate and not give outer functions a
chance for properly freeing resources?
Is it so hard to design dtors to be nothrow? Why should it do anything that
requires check and throw?
The only dtor I recall that could throw was closing file, flushing buffer on
the way that could fail. And leaked to dtor with calling the general Close()
if the file was opened. But it is a sucking design ayway. When you do such
stuff you shall call Close() explicitely and carry on if it survived. If
nuking the object before that; for an implicit call it can just do the core
work, release the resource and swallow. Those interested in completion did
have a chance to force it earlier.
I am not so sure whether a destructor should never throw.
google for expert articles, mentors wrote a plenty of stuff about that, and
damn convincing too.
My code handles only the exceptions I know to handle.
In this case swallowing is the proper handling by default.
It might be dangerous to catch unknown exceptions and ignore them.
So the design shall not rely on dtors throwing in the first place, then said
danger is gone for good. Call every "commit" explicitly, while rollback and
get-rid type operations shall just do the best effort.