GitHub
CERT Secure Coding

ERR55-CPP. Honor exception specifications

The C++ Standard, [except.spec], paragraph 8 [ ISO/IEC 14882-2014 ], states the following :

A function is said to allow an exception of type E if the constant-expression in its noexcept-specification evaluates to false or its dynamic-exception-specification contains a type T for which a handler of type T would be a match (15.3) for an exception of type E .

If a function throws an exception other than one allowed by its exception-specification , it can lead to an implementation-defined termination of the program ([except.spec], paragraph 9).

If a function declared with a dynamic-exception-specification throws an exception of a type that would not match the exception-specification , the function std::unexpected() is called. The behavior of this function can be overridden but, by default, causes an exception of std::bad_exception to be thrown. Unless std::bad_exception is listed in the exception-specification , the function std::terminate() will be called.

Similarly, if a function declared with a noexcept-specification throws an exception of a type that would cause the noexcept-specification to evaluate to false , the function std::terminate() will be called.

Calling std::terminate() leads 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 allowed exceptions.

Noncompliant Code Example

In this noncompliant code example, a function is declared as nonthrowing, but it is possible for std::vector::resize() to throw an exception when the requested memory cannot be allocated.

Non-compliant code
#include <cstddef>
#include <vector>
 
void f(std::vector<int> &v, size_t s) noexcept(true) {
  v.resize(s); // May throw 
}

Compliant Solution

In this compliant solution, the function's noexcept-specification is removed, signifying that the function allows all exceptions.

Compliant code
#include <cstddef>
#include <vector>

void f(std::vector<int> &v, size_t s) {
  v.resize(s); // May throw, but that is okay
}

Noncompliant Code Example

In this noncompliant code example, the second function claims to throw only Exception1 , but it may also throw Exception2.

Non-compliant code
#include <exception>
 
class Exception1 : public std::exception {};
class Exception2 : public std::exception {};

void foo() {
  throw Exception2{}; // Okay because foo() promises nothing about exceptions
}

void bar() throw (Exception1) {
  foo();    // Bad because foo() can throw Exception2
}

Compliant Solution

This compliant solution catches the exceptions thrown by foo().

Compliant code
#include <exception>
 
class Exception1 : public std::exception {};
class Exception2 : public std::exception {};

void foo() {
  throw Exception2{}; // Okay because foo() promises nothing about exceptions
}

void bar() throw (Exception1) {
  try {
    foo();
  } catch (Exception2 e) {
    // Handle error without rethrowing it
  }
}

Compliant Solution

This compliant solution declares a dynamic exception-specification for bar() , which covers all of the exceptions that can be thrown from it.

Compliant code
#include <exception>
 
class Exception1 : public std::exception {};
class Exception2 : public std::exception {};

void foo() {
  throw Exception2{}; // Okay because foo() promises nothing about exceptions
}

void bar() throw (Exception1, Exception2) {
  foo();
}

Implementation Details

Some vendors provide language extensions for specifying whether or not a function throws. For instance, Microsoft Visual Studio provides __declspec(nothrow)) , and Clang supports __attribute__((nothrow)) . Currently, the vendors do not document the behavior of specifying a nonthrowing function using these extensions. Throwing from a function declared with one of these language extensions is presumed to be undefined behavior .

Risk Assessment

Throwing unexpected exceptions disrupts control flow and can cause premature termination and denial of service .

Rule Severity Likelihood Detectable Repairable Priority Level
ERR55-CPP Low Likely No Yes P6 L2

Automated Detection

Tool

Version

Checker

Description

Astrée

25.10

unhandled-throw-noexcept
Partially checked
Axivion Bauhaus Suite

7.2.0

CertC++-ERR55
CodeSonar
9.1p0

LANG.STRUCT.EXCP.THROW

Use of throw

Helix QAC

2025.2

C++4035, C++4036, C++4632


LDRA tool suite
9.7.1

56 D

Partially implemented

Parasoft C/C++Test
2025.2
CERT_CPP-ERR55-a
Where a function's declaration includes an exception-specification, the function shall only be capable of throwing exceptions of the indicated type(s)
Polyspace Bug Finder

R2025b

CERT C++: ERR55-CPPChecks for noexcept functions exiting with exception (rule fully covered)
RuleChecker
25.10
unhandled-throw-noexcept
Partially checked

Search for vulnerabilities resulting from the violation of this rule on the CERT website .

SEI CERT C++ Coding StandardERR50-CPP. Do not abruptly terminate the program

Bibliography

[ GNU 2016 ]"Declaring Attributes of Functions"
[ ISO/IEC 14882-2014 ]Subclause 15.4, "Exception Specifications"
[ MSDN 2016 ]" nothrow (C++)"