When an exception is caught by a function-try-block handler in a constructor, any fully constructed base classes and class members of the object are destroyed prior to entering the handler [ISO/IEC 14882-2014]. Similarly, when an exception is caught by a function-try-block handler in a destructor, all base classes and nonvariant class members of the objects are destroyed prior to entering the handler. Because of this behavior, the C++ Standard, [except.handle], paragraph 10, states the following:
Referring to any non-static member or base class of an object in the handler for a function-try-block of a constructor or destructor for that object results in undefined behavior.
Do not reference base classes or class data members in a constructor or destructor function-try-block handler. Doing so results in undefined behavior.
Noncompliant Code Example
In this noncompliant code example, the constructor for class C
handles exceptions with a function-try-block. However, it generates undefined behavior by inspecting its member field str
.
#include <string> class C { std::string str; public: C(const std::string &s) try : str(s) { // ... } catch (...) { if (!str.empty()) { // ... } } };
Compliant Solution
In this compliant solution, the handler inspects the constructor parameter rather than the class data member, thereby avoiding undefined behavior.
#include <string> class C { std::string str; public: C(const std::string &s) try : str(s) { // ... } catch (...) { if (!s.empty()) { // ... } } };
Risk Assessment
Accessing nonstatic data in a constructor's exception handler or a destructor's exception handler leads to undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ERR53-CPP | Low | Unlikely | Medium | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Astrée | 22.10 | exception-handler-member-access | Fully checked |
Axivion Bauhaus Suite | 7.2.0 | CertC++-ERR53 | |
Clang | 3.9 | -Wexceptions | |
Helix QAC | 2024.2 | C++3510 | |
Klocwork | 2024.2 | MISRA.CTOR.TRY.NON_STATIC | |
LDRA tool suite | 9.7.1
| 549 S | Partially implemented |
Parasoft C/C++test | 2023.1 | CERT_CPP-ERR53-a | Handlers of a function-try-block implementation of a class constructor or destructor shall not reference nonstatic members from this class or its bases |
Polyspace Bug Finder | R2024a | CERT C++: ERR53-CPP | Checks for constructor or destructor function-try-block handler referencing base class or class data member (rule fully covered) |
RuleChecker | 22.10 | exception-handler-member-access | Fully checked |
Related Vulnerabilities
Search for other vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
[MISRA 2008] | Rule 15-3-3 (Required) |
Bibliography
[ISO/IEC 14882-2014] | Subclause 15.3, "Handling an Exception" |