1

The destructor of the the C++11 std::exception base class is not noexcept, and thus may (in theory) throw an exception, which consequent relaxed permission for all its derived classes (including std::bad_alloc and std::runtime_error). The destructor of the C++98 std::exception however had a throw() exception specification, indicating it was not permitted to throw exceptions. Why the difference? Why is it now permitted to throw exceptions? The permission is particularly odd given that the std::exception constructors are now noexcept: you can safely construct such an object, but you can not safely destroy it: the opposite of the normal behaviour.

Having the destructor of an exception class throw an exception is usually disastrous. What can cause std::exception::~exception to throw an exception?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • 1
    That declaration shown on cppreference actually is `noexcept`. Destructors are `noexcept` unless declared `noexcept(false)` – Justin Apr 25 '18 at 15:17

2 Answers2

6

It is noexcept(true) indeed. Since C++11, for destructors with no exception specification explicitly provided the exception specification is considered to be noexcept(true).

Except that if no exception specification is explicitly provided, the exception specification is considered to be one that would be used by the implicitly-declared destructor (see below). In most cases, this is noexcept(true). Thus a throwing destructor must be explicitly declared noexcept(false). (since C++11)

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • A diabolic implementation would still be allowed to make this implicitly `noexcept(false)` by having an attribute that would not be `noexcept(true)`, no? – Holt Apr 25 '18 at 15:39
  • @Holt It should match the one for the implicitly-declared destructor; for `std::exception` it should be `noexcept(true)` unless `std::exception` is implemented with a base or member whose destructor is `noexcept(false)`... – songyuanyao Apr 25 '18 at 15:46
1

[res.on.exception.handling]/3:

Destructor operations defined in the C++ standard library shall not throw exceptions. Every destructor in the C++ standard library shall behave as if it had a non-throwing exception specification.

cpplearner
  • 13,776
  • 2
  • 47
  • 72