Consider the following program:
#include <type_traits>
struct Thrower
{
~Thrower() noexcept(false) { throw 1; }
};
struct Implicit
{
Thrower t;
};
static_assert(!std::is_nothrow_destructible<Implicit>::value, "Implicit");
struct Explicit
{
~Explicit() {}
Thrower t;
};
static_assert(!std::is_nothrow_destructible<Explicit>::value, "Explicit");
With g++-4.8.1
, there is a static assertion failure on Explicit
-- it seems to think that ~Explicit()
is noexcept
. This does not match my expectations. According to §12.4.3:
A declaration of a destructor that does not have an exception-specification is implicitly considered to have the same exception-specification as an implicit declaration
The funny thing here is the check of Implicit
seems to be behaving according to my interpretation of §15.4.14 (through §12.4.7).
...If f is an...destructor...it's implicit exception-specification specifies...f has the exception-specification
noexcept(true)
if every function it directly invokes allows no exceptions.
g++-4.7
lacks is_nothrow_destructable
, I wrote my own to check the behavior in 4.7. The program seems to compile perfectly fine. I reserve the right for this to be completely wrong and the source of my confusion:
template <typename T>
struct is_nothrow_destructible
{
static constexpr bool value = noexcept(std::declval<T>().~T());
};
TL;DR: Why does g++-4.8.1
think that an explicitly-declared destructor with no exception specification is always noexcept(true)
?
Update: I opened a bug on this: 57645. If you really need to work around this issue, you can add an exception specification to the destructor (like Thrower
has in the example).