Boost logo

Boost :

Subject: Re: [boost] [C++11] If you have an old class with a throwing destructor...
From: Jonathan Wakely (jwakely.boost_at_[hidden])
Date: 2013-09-16 08:12:45


On 9 September 2013 22:57, Niall Douglas wrote:
> On 9 Sep 2013 at 13:11, Nevin Liber wrote:
>
>> > In C++03 it was always best practice to *always* wrap your
>> > destructors in a try...catch clause.
>>
>> No; the best practice is not to throw from a destructor.
>
> Sorry, my unclear phrasing again ... by wrapping destructors I
> specifically meant:
>
> destructor::~destructor()
> { try {
> ...
> } catch(...) { /* do something useful */ } }
>
> Indeed I once had some python executed by my build script to
> auto-insert those destructor wrappers because I kept forgetting to do
> it.
>
> The problem is that unless some code is specifically marked as
> noexcept, you have to assume it can throw, and as destructors ought
> to be noexcept, that means lots of try...catch verbiage.

I disagree that littering destructors with try-catch is best practice.

>> > I already get caught enough times forgetting to mark
>> > move constructors as noexcept, without which some STL implementations
>> > will silently disable move construction completely.
>>
>> That seems buggy, other than the well-defined cases such as vector using
>> the equivalent of move_if_noexcept under the covers when growing a vector.
>
> I think it's buggy if they silently disable move construction and
> don't tell you (older versions of libstdc++ I'm looking at you).

You mean pre-C++11 versions? It seems a bit picky to complain about
non-conformance in an experimental mode shipped before the standard
was finished.

> libc++ at least is kind enough to refuse to compile, perhaps even a
> bit too anally so.

Could you clarify what you're talking about? You're making a lot of
pretty vague statements, could you show some code? I would be quite
surprised if valid code that compiles with libstdc++ doesn't compile
with libc++.

> Ideally a STL should issue a compiler warning if it refuses to use
> you move constructor for some reason. It is, after all, a quality of
> implementation issue.

No, it's required behaviour, the relevant members of std::vector say
"If an exception is thrown other than by the move constructor of a
non-CopyInsertable T there are no effects." In order to meet that
guarantee a throwing move constructor must not be used if the type is
CopyInsertable, i.e. it must "refuse" to use the move constructor, to
avoid un-recoverable data loss.

Apart from being a bogus warning, it would be rather hard for the
library to issue a compiler warning in that situation anyway.


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