Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Under certain circumstances, terminating a function by throwing an exception will trigger undefined behavior. For instance, the C++ Standard, [basic.stc.dynamic.deallocation], paragraph 3 , states in part [ISO/IEC 14882-2014], states in part:

If a deallocation function terminates by throwing an exception, the behavior is undefined.

In these situations, the function should logically be declared noexcept because throwing an exception from the function can never have well-defined behavior. The C++ Standard, [except.spec], paragraph 15, states [ISO/IEC 14882-2014]:

A deallocation function with no explicit exception-specification is treated as if it were specified with noexcept(true).

...

In this noncompliant code example, the class destructor does not meet the implicit noexcept guarantee because it may throw an exception even if it was called as the result of an exception being thrown. Consequently, it is declared as noexcept(false) but still can trigger undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <stdexcept>
 
class S {
  bool shouldThrow() const;
 
public:
  ~S() noexcept(false) {
    // Normal processing
    if (shouldThrow()) {
      throw std::logic_error("Something bad");
    }
  }
};

...

In this noncompliant code example, a global deallocation is declared noexcept(false) and throws an exception if some conditions are not properly met. However, throwing from a deallocation function results in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <stdexcept>
 
bool performDealloc(void *);
 
void operator delete(void *ptr) noexcept(false) {
  if (performDealloc(ptr)) {
    throw std::logic_error("Something bad");
  }
}

...