MISRA C++:2008 Rule 15-3-1
Exceptions shall be raised only after startup and before termination of the program
Since R2020b
Description
Rule Definition
Exceptions shall be raised only after startup and before termination of the program.
Rationale
In c++, the process of exception handling runs during execution of
main()
, where exceptions arising in different scopes are handled by
exception handlers in the same or adjacent scopes. Before starting the execution of
main()
, the compiler is in startup phase, and after finishing the
execution of main()
, the compiler is in termination phase. During these
two phases, the compiler performs a set of predefined operations but does not execute any
code.
If an exception is raised during either the startup phase or the termination phase, you
cannot write an exception handler that the compiler can execute in those phases. For
instance, you might implement main()
as a
function-try-catch
block to handle exceptions. The
catch
blocks in main()
can handle only the
exceptions raised in main()
. None of the catch
blocks
can handle exceptions raised during startup or termination phase. When such exceptions are
raised, the compiler might abnormally terminate the code execution without unwinding the
stack. Consider this code where the construction and destruction of the static object
obj
might cause an
exception.
class A{ A(){throw(0);} ~A(){throw(0)} }; static A obj; main(){ //... }
obj
is constructed by calling A()
before
main()
starts, and it is destroyed by calling ~A()
after main()
ends. When A()
or ~A()
raises an exception, no exception handler can be matched with them. Based on the
implementation, such an exception can result in program termination without stack unwinding,
leading to memory leak and security vulnerabilities.Avoid operations that might raise an exception in the parts of your code that might be executed before startup or after termination of the program. For instance, avoid operations that might raise exceptions in the constructor and destructor of static or global objects.
Polyspace Implementation
Polyspace® flags global or static variable declaration that uses a callable entity that might raise an exception. For instance:
Functions: When you call an initializer function or constructor directly to initialize a global or static variable, Polyspace checks whether the function raises an exception and flags the variable declaration if the function might raise an exception. Polyspace deduces whether a function might raise an exception regardless of its exception specification. For instance, If a
noexcept
constructor raises an exception, Polyspace flags it. If the initializer or constructor calls another function, Polyspace assumes the called function might raise an exception only if it is specified asnoexcept(<false>)
. Some standard library functions, such as the constructor ofstd::string
, uses pointers to functions to perform memory allocation, which might raise exceptions. Polyspace does not flag the variable declaration when these functions are used.External function: When you call external functions to initialize a global or static variable, Polyspace flags the declaration if the external function is specified as
noexcept(<false>)
.Virtual function: When you call a virtual function to initialize a global or static variable, Polyspace flags it if the virtual function is specified as
noexcept(<false>)
in any derived class. For instance, if you use a virtual initializer function that is declared asnoexcept(<true>)
in the base class, andnoexcept(<false>)
in a subsequent derived class, Polyspace flags it.Pointers to function: When you use a pointer to a function to initialize a global or static variable, Polyspace assumes that pointer to function do not raise exceptions.
Polyspace ignores:
Exceptions raised in destructors
Exceptions raised in
atext()
operations
Polyspace also ignores the dynamic context when checking for exceptions. For instance, you might initialize a global or static variable by using function that raises exceptions only in certain dynamic context. Polyspace flags such a declaration even if the exception might never be raised. You can justify such a violation using comments in Polyspace.
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 |
Version History
Introduced in R2020b