Boost logo

Boost :

From: scleary_at_[hidden]
Date: 2001-06-18 16:04:47


> From: "David Abrahams" <david.abrahams_at_[hidden]>
> > From: "Vesa Karvonen" <vesa.karvonen_at_[hidden]>
> > >
> > > In the C++ standard library, as well as in Boost, there is a
requirement
> > > that objects may not throw in destructors. Unfortunately this is very
> > > difficult to ensure both in theory and in practice
> >
> > Not in my experience, FWIW.

Not in mine, either.

> Throwing in a destructor is indeed bad practice and should be
> discouraged.

Yes, for the following reasons:
  1) An object with a throwing destructor *cannot* be used with the STL if
there is *any* chance that it will be destructed [17.4.3.6/2].
  2) It makes throwing *any* exception a risky business -- if there's an
object with a throwing destructor on the stack, your program's blown away.
  3) It's impossible to have dynamic arrays of such objects.

> > From a standards POV, I think this change would be a mistake.
> > auto_ptr<T>::reset() is currently guaranteed not to throw
> > an exception.
>
> I'm not entirely convinced that this is true. Perhaps I'm missing a
critical
> piece of knowledge.

[20.4.5.2/7]: "void reset(X* p=0) throw();"

> Also keep in mind, that the Boost smart pointer nothrow guarantee is, both
in
> practice and in theory, rather weak, because Boost smart pointers do not
use
> exception specifications.

I disagree. Exception specifications are IMO a
guarantee-of-quality-of-implementation style of sugar, on the same level as
automatic pre/post-condition testing, and the lack of them do not make
programs "weak".

> I think that the current nothrow guarantee of smart pointer reset()
(including
> std::auto_ptr and boost::shared_ptr) gives a false sense of exception
safety,
> because it simply doesn't guarantee any consistent programmatically
detectable
> effect - in the case that an exception is actually throw.

Neither does any other code producing undefined behaviour. Hence the name,
"undefined"...

> Exceptions are an interesting topic and I don't like defeatism.

I don't like defeatism, either. However, Dave and others have looked at
every possible side of this for years; if there was a better solution, I
think in this case it would have been found.

> As I have demonstrated, the technique that I have described:
> - Prevents double deletion of the old pointer.
> - Prevents leaking the new pointer.
> - Removes the nothrow exception specification (which is practically
useless
> anyway).

Just wanted to point out that the nothrow requirement also prevents double
deletion and leaking, and the nothrow exception specification can be useful
(for example, in satisfying nothrow requirements...)

You mentioned above that throwing destructors should be discouraged, and so
they should be. Discouraged strongly. By refusing to work with them. :)

Sorry -- just had to put in my 2 bits! :)

        -Steve


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk