CERT.ERR.UNCAUGHT_STATIC_INIT
Handle exceptions thrown before main() begins executing.
The CERT.ERR.UNCAUGHT_STATIC_INIT checker detects static and thread-local objects whose construction, destruction, or initialization can throw an exception outside a catchable scope. An exception thrown during static initialization can terminate the program before main() begins. A potentially throwing destructor can also terminate the program during termination or thread exit.
Vulnerability and risk
Exceptions thrown during static initialization are not handled by a try statement in main(). If construction or initialization throws, the runtime calls std::terminate() before main() begins. A non-noexcept destructor for a static or thread-local object can throw during program termination or thread exit.
Mitigation and prevention
Ensure that constructors, destructors, and initializers for static and thread storage duration objects do not throw. Mark them noexcept where applicable, and handle errors before static initialization or through an explicit error reporting mechanism.
Vulnerable code example
#include <stdexcept>
int load_value();
struct Config {
Config() : value(load_value()) {}
int value;
};
Config global_config; // CERT.ERR.UNCAUGHT_STATIC_INIT
The constructor for global_config can throw while the runtime initializes the object before main() begins.
Fixed code example
#include <optional>
int load_value() noexcept;
struct Config {
Config() noexcept : value(load_value()) {}
int value;
};
Config global_config; // No CERT.ERR.UNCAUGHT_STATIC_INIT defect
The fixed example uses a non-throwing initializer and constructor. The same principle applies to static and thread-local destructors.
Limitations
This checker provides shallow modern AST coverage. It does not provide full path-based exception-flow analysis or model every indirect call that can throw.