CERT.ERR.UNCAUGHT_STATIC_INIT

Handle exceptions thrown before main() begins executing.

This checker is applicable only to the modern engine.

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

Copy
#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

Copy
#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.