Boost logo

Boost :

Subject: Re: [boost] [C++11] If you have an old class with a throwing destructor...
From: Neil Groves (neil_at_[hidden])
Date: 2013-09-16 09:54:11


On Mon, Sep 16, 2013 at 1:28 PM, Jonathan Wakely
<jwakely.boost_at_[hidden]> wrote:
> On 16 September 2013 13:12, Jonathan Wakely <jwakely.boost_at_[hidden]> wrote:
>> 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.

The use of an explicit try-catch block is rarely the optimal solution
in a destructor. I don't think we should consider recommending this
practice. I am open to exploring the potential solutions involving
decorating the destructor declarations/definitions to improve
behaviour across compiler versions. I am unclear about how clever the
C++11 has_trivial_destructor meta-functions are. Do they generally
work when an explicitly defined noexcept destructor is declared?

My opinion is that we should provide the support for broken compiler
versions if and only if the additional verbiage doesn't cause a
performance regression for correct compilers.

>>
>>
>>>> > 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.
>
> There were some problems caused by the little-known fact that
> is_nothrow_move_constructible depends on a noexcept destructor as well
> as nothrow move constructor and until G++ implemented the implicit
> noexcept on destructors you needed to explicitly mark your types'
> destructors as noexcept to make the library do the right thing. That
> was actually a problem in the G++ front-end, libstdc++ was doing the
> right thing based on the value of is_nothrow_move_constructible. If
> the compiler causes the value of is_nothrow_move_constructible to be
> wrong there's not much the library can do.
>

Additionally it doesn't seem that there is much that we Boost
developers can do for the broken versions without deteriorating the
results for working versions. I therefore vote for doing nothing!

Neil Groves


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