Анализатор обнаружил конструктор исключения, из которого может быть брошено другое исключение. Использование такого класса может привести к неожиданному поведению программы при обработке исключений.
Рассмотрим синтетический пример:
#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 }
В коде функции 'example' программист пытается обработать возникшее исключение 'divide_by_zero_error', однако вместо этого будет сформировано исключение 'std::runtime_error' и не перехвачено последующим 'catch'-блоком. Это приведет к тому, что исключение покинет функцию 'example', что может привести к следующим ситуациям:
При разработке и использовании собственных классов исключений нужно проявлять особую бдительность, поскольку исключения в их конструкторах могут возникнуть в неожиданных местах, например при вызове других функций. В следующем примере при создании логирующего исключения может возникнуть второе исключение из функции 'Log':
#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); // <= } };
Данная диагностика классифицируется как: