On Mon, Sep 16, 2013 at 1:28 PM, Jonathan Wakely
On 16 September 2013 13:12, Jonathan Wakely
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