If a function declared with an exception-specification throws an exception of a type not included in the specification, the function unexpected()
is called. The behaviour of this function can be overridden within a project, but by default causes an exception of std::bad_exception
to be thrown. Unless std::bad_exception
is listed in the exception-specification, the terminate()
function will be called, leading to implementation-defined termination of the program.
To prevent abnormal termination of the program, any function that declares an exception-specification should restrict itself, as well as any functions it calls, to throwing only exceptions listed in its exception-specification.
Non-Compliant Code Example
In this non-compliant code example, the second function claims to throw only exception1
, but it may also throw exception2
.
class exception1 : public exception {}; class exception2 : public exception {}; void foo() { throw exception2; // ok...since foo() promises nothing wrt exceptions } void bar() throw (exception1) { foo(); // bad, since foo() can throw exception2 }
Compliant Solution
A simple compliant solution is to catch any exceptions thrown by foo{}
void bar() throw (exception1) { try { foo(); } catch (...) { // handle error, without re-throwing it } }
Risk Assessment
Throwing unexpected exceptions disrupts control flow and can cause premature termination and denial of service.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ERR37-CPP |
low |
likely |
low |
P9 |
L2 |
Bibliography
[ISO/IEC 14882-2003]
[MISRA 08] Rule 15-5-2
ERR36-CPP. Multiple catch handlers to a try block should order their exceptions from most derived to most basic 12. Exceptions and Error Handling (ERR) ERR38-CPP. Deallocation functions must not throw exceptions