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 |
1 (low) |
3 (likely) |
1 (low) |
P3 |
L3 |
References
[[ISO/IEC 14882-2003]]
[[MISRA 08]] Rule 15-5-2
ERR09-CPP. Throw anonymous temporaries and catch by reference 12. Exceptions and Error Handling (ERR) ERR31-CPP. Don't redefine errno