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