Rule A15-2-1 (required, implementation, automated)
Constructors that are not noexcept shall not be invoked before program startup.
Rationale
Before the program starts executing the body of main function, it is in a start-up phase, constructing and initializing static objects. There is nowhere an exception handler can be placed to catch exceptions thrown during this phase, so if an exception is thrown it leads to the program being terminated in an implementation-defined manner.
Such errors may be more difficult to find because an error message can not be logged, due to lack of exception handling mechanism during static initialization.
Example
//% $Id: A15-2-1.cpp 271927 2017-03-24 12:01:35Z piotr.tanski $
#include <cstdint>
#include <stdexcept>
class A
{
public:
A() noexcept : x(0)
{
// ...
}
explicit A(std::int32_t n) : x(n)
{
// ...
throw std::runtime_error("Unexpected error");
}
A(std::int32_t i, std::int32_t j) noexcept : x(i + j)
{
try
{
// ...
throw std::runtime_error("Error");
// ...
}
catch (std::exception& e)
{
}
}
private:
std::int32_t x;
};
static A a1;
// Compliant - default constructor of type A is noexcept
static A a2(5); // Non-compliant - constructor of type A throws, and the
// exception will not be caught by the handler in main function
static A a3(5, 10); // Compliant - constructor of type A is noexcept, it
// handles exceptions internally
int main(int, char**)
{
try
{
// program code
}
catch (...)
{
// Handle exceptions
}
return 0;
}
See also
SEI CERT C++ [10]: ERR51-CPP. Handle all exceptions.