AUTOSAR C++14 Rule A15-2-1
Constructors that are not noexcept shall not be invoked before program startup
Description
Rule Definition
Constructors that are not noexcept shall not be invoked before program startup.
Rationale
In C++, the compiler responds to an exception by following these steps:
The compiler tries to match the exception with a handler in the current scope or a higher scope.
If the exception matches with a handler, then the handler accepts the exception and begins stack unwinding. During stack unwinding, The program execution moves from the scope that produces the exception to the outer scopes in reverse order. The program execution then invokes the destructors for each variable on the stack that are not destroyed yet. After stack unwinding, program execution resumes from the line immediately after the triggered handler.
If the exception does not match a handler, then the compiler terminates the execution in an implementation-defined manner. That is, the exact process of program termination depends on the particular set of software and hardware that you use. For instance, the compiler might invoke
std::terminate()
, which in turn might invokestd::abort()
to abnormally abort the execution. Based on the implementation, the stack might not be unwound before the program is aborted. If the stack is not unwound before program termination, then the destructors of the variables in the stack are not invoked, leading to resource leak and security vulnerabilities.
Before program startup, the constructors of static or global objects are invoked to
construct and initialize these objects. If such a constructor raises an exception, the
compiler might abnormally terminate the code execution without unwinding the stack. Consider
this code where the constructor of the static object obj
might cause an
exception.
class A{ A(){ //... } }; static A obj; main(){ //... }
obj
is constructed by calling A()
before
main()
starts. Because A()
is called before program
startup, no exception handler can be matched with exceptions raised by
A()
. Based on the implementation, such an exception can result in
program termination without stack unwinding, leading to memory leak and security
vulnerabilities.Because exceptions raised by constructors of static or global objects cannot be matched
to an exception handler, declare these constructors as noexcept
.
Polyspace Implementation
Polyspace® flags statements where non-noexcept
constructors of a
static or global object are directly invoked. It also highlights the noncompliant
constructors.
Troubleshooting
If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.
Examples
Check Information
Group: Exception Handling |
Category: Required, Automated |