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.
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()) { // ... } } }; |
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()) { // ... } } }; |
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 |
Tool | Version | Checker | Description |
---|---|---|---|
Astrée | exception-handler-member-access | Fully checked | |
Axivion Bauhaus Suite | CertC++-ERR53 | ||
Clang | -Wexceptions | ||
Helix QAC | C++3510 | ||
Klocwork | MISRA.CTOR.TRY.NON_STATIC | ||
LDRA tool suite | 549 S | Partially implemented | |
Parasoft C/C++test | 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 | CERT C++: ERR53-CPP | Checks for constructor or destructor function-try-block handler referencing base class or class data member (rule fully covered) | |
RuleChecker | exception-handler-member-access | Fully checked |
Search for other vulnerabilities resulting from the violation of this rule on the CERT website.
[MISRA 2008] | Rule 15-3-3 (Required) |
[ISO/IEC 14882-2014] | Subclause 15.3, "Handling an Exception" |