Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: moved text to after code snippet

...

In this noncompliant code example, the SomeClass destructor attempts to handle exceptions thrown from the destructor of the bad_member subobject by absorbing them. However, the C++ Standard, [except.handle], paragraph 15 [ISO/IEC 14882-2014], states in part:

The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor.

Consequently, the caught exception will inevitably escape from the SomeClass destructor because it is implicitly rethrown when control reaches the end of the function-try-block handler.

Code Block
bgColor#FFcccc
langcpp
#include <stdexcept>
 
class SomeClass {
  class Bad {
    bool has_error() const;
  public:
    ~Bad() noexcept(false) {
      if (has_error()) {
        throw std::logic_error("Something bad");
      }
    }
  } bad_member;

public:
  ~SomeClass()
  try {
    // ...
  } catch(...) {
    // Handle the exception thrown from the Bad destructor.
  }
};

However, the C++ Standard, [except.handle], paragraph 15 [ISO/IEC 14882-2014], states in part:

The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor.

Consequently, the caught exception will inevitably escape from the SomeClass destructor because it is implicitly rethrown when control reaches the end of the function-try-block handler/

Compliant Code Example

A destructor should perform the same way whether or not there is an active exception. Typically, this means that it should invoke only operations that do not throw exceptions, or it should handle all exceptions and not rethrow them (even implicitly). In this compliant solution, all exceptions are caught in the function-try-block and the exception will not be rethrown because control does not reach the end of the handler due to the explicit return statement. This handler will catch the exception thrown by Bad::~Bad() when bad_member is destroyed, and it will also catch any exceptions thrown within the compound statement of the function-try-block.

...