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.