The analyzer has detected an exception constructor that may throw another exception. Using such a class may cause the program to behave unexpectedly when handling exceptions.
Consider the following synthetic example:
#include <stdexcept> class divide_by_zero_error : public std::invalid_argument { public: divide_by_zero_error() : std::invalid_argument("divide_by_zero") { .... if (....) { throw std::runtime_error("oops!"); // <= } } }; void example(int a, int b) { try { if (b == 0) throw divide_by_zero_error (); .... } catch (const divide_by_zero_error &e) { .... } // my_exception thrown and unhandled }
In the code of the 'example' function, the programmer intends the raised 'divide_by_zero_error' exception to be handled, but instead of it, an 'std::runtime_error' exception will be thrown, which will not be caught by the subsequent 'catch' block. As a result, the exception will leave the 'example' function, thus causing one of the following situations:
Write and use custom exception classes with particular care because their constructors may throw exceptions at unexpected points – for example, when calling other functions. In the following example, when creating a logging exception, a second exception may be thrown by the 'Log' function:
#include <ios> static void Log(const std::string& message) { .... // std::ios_base::failure may be thrown by stream operations throw std::ios_base::failure("log file failure"); } class my_logging_exception : public std::exception { public: explicit my_logging_exception(const std::string& message) { Log(message); // <= } };
This diagnostic is classified as: