Cppcoreguidelines: Why explicitly destructors noexcept, when they are so by default?

Created on 27 Sep 2015  路  2Comments  路  Source: isocpp/CppCoreGuidelines

I have my remarks about C.37: Make destructors noexcept, because, well, Bjarne and Scott told me so:

Generated destructors are implicitly noexcept [1,2]. 
Declaring a destructors noexcept explicitly is harmless and unconventional [2]. 

I would from those suggest something like:

C.37: Do not write noexcept at destructor specifications

Reasons (rationales): because it is added implicitly by the compiler

Examples:

~T() noexcept {} //No need to
~U() {} //Fine

Enforcement: if a compiler detects a user adding noexcept to a destructor specifier, it should give a warning destructor marked noexcept, when it already is by default

References:

[1] Bjarne Stroustrup's C++11 FAQ: 'A destructor shouldn't throw; a generated destructor is implicitly noexcept (independently of what code is in its body) if all of the members of its class have noexcept destructors.'
[2] Scott Meyers. Effective Modern C++ (1st Edition). 2014. ISBN: 978-1-491-90399-5. Item 14, page 94: 'By default, all memory deallocation functions and all destructors -both user-defined and compiler-generated- are implicitly noexcept. There is thus no need to declare them noexcept. (Doing so doesn't hurt anything, it's just unconventional.)'

Notes: the original rule stated to always write noexcept

Discussion: none

[1] Bjarne Stroustrup's C++11 FAQ: 'A destructor shouldn't throw; a generated destructor is implicitly noexcept (independently of what code is in its body) if all of the members of its class have noexcept destructors.'
[2] Scott Meyers. Effective Modern C++ (1st Edition). 2014. ISBN: 978-1-491-90399-5. Item 14, page 94: 'By default, all memory deallocation functions and all destructors -both user-defined and compiler-generated- are implicitly noexcept. There is thus no need to declare them noexcept. (Doing so doesn't hurt anything, it's just unconventional.)'

Most helpful comment

Not all destructors are noexcept by default; one throwing member poisons the whole class hierarchy

#include <soci/once-temp-type.h>
#include <type_traits>
struct X {
   soci::details::once_temp_type boom; // happens to have a throwing destructor
    ~X() { } // implicitly noexcept(false)
};
// fails this assert
static_assert(std::is_nothrow_destructible<X>::value == true, "");

All 2 comments

Not all destructors are noexcept by default; one throwing member poisons the whole class hierarchy

#include <soci/once-temp-type.h>
#include <type_traits>
struct X {
   soci::details::once_temp_type boom; // happens to have a throwing destructor
    ~X() { } // implicitly noexcept(false)
};
// fails this assert
static_assert(std::is_nothrow_destructible<X>::value == true, "");

Thanks for the awesome answer. I guess I can close this Issue then :-)

Was this page helpful?
0 / 5 - 0 ratings