Warning | ||
---|---|---|
| ||
This practice is an incomplete work in progress. It may contain errors and should not be applied until this notice has been removed. |
A proper Proper handling of errors and exceptional situations is essential for the continued correct operation of software (see ERR00-CPP. Adopt and implement a consistent and comprehensive error-handling policy). The preferred mechanism for reporting errors in a C++ program is exceptions (see ERR07-CPP. Use exception handling rather than error codes). A number of core language facilities, including dynamic_cast
, operator new()
, and typeid
, report failures by throwing exceptions. In addition, the C++ Standard Library standard library makes heavy use of exceptions to report several different kinds of failures. Few C++ programs manage to avoid making use of using some of these facilities. ThusConsequently, the vast majority of C++ programs must be prepared for exceptions to occur and must handle each appropriately.
Since Because exceptions introduce code paths into a program that wouldn't would not exist in their absence, it is important to consider the effects of code taking such paths and to avoid any undesirable effects that might arise otherwise. Some such effects include a failure to release an acquired resource and , thereby introducing a leak, a and failure to re-establish reestablish a class invariant after a partial update to an object , or even a partial object update while maintaining all invariants. Code that avoids any such undesirable effects is said to be exception safe.
Based on the effects mentioned above we can distinguish among preceding effects, the following table distinguishes three kinds of exception safety guarantees in decreasing desirability:
Guarantee | Description | Example |
---|---|---|
Strong | The strong exception safety guarantee is a property of an operation such that, in addition to satisfying the basic exception safety guarantee, if the operation terminates by raising an exception, it has no observable effects on program state. (See strong exception safety.) | |
Basic | The basic exception safety guarantee is a property of an operation such that, if the operation terminates by raising an exception, it preserves program state invariants and prevents resource leaks. (See basic exception safety.) | |
None | Code that provides neither the strong nor the basic exception safety guarantee is not exception safe. |
...
Anchor | ||||
---|---|---|---|---|
|
...
Noncompliant Code Example (No Exception Safety)
The following noncompliant code example shows a flawed implementation of the copy assignment operator of a dynamically sizable array class. The implicit invariants of the class are that the array
member is a valid (possibly null) pointer and that the nelems
member stores the number of elements in the array pointed to by array
.
The copy assignment operator is flawed because it fails to provide any exception safety guarantee. The function deallocates array
and assigns the element counter, nelems
, before allocating a new block of memory for the copy. As a result, when the new expression throws an exception, the function will have modified the state of both member variables in a way that violates the implicit invariants of the class. Consequently, the object of the class is in an indeterminate state and any operation on it, including its destruction, results in undefined behavior.
Code Block | ||||
---|---|---|---|---|
| ||||
class IntArray { int *array; std::size_t nelems; public: // ... ~IntArray() { delete[] array; } IntArray& operator=(const IntArray &rhs) { if (this != &rhs) { delete[] array; nelems = rhs.nelems; array = new int[nelems]; std::memcpy(array, rhs.array, nelems * sizeof *array); } return *this; } // ... }; |
...
Compliant Solution (Strong Exception Safety)
In the this compliant solution below, the copy assignment operator provides the Strong Exception Safety the strong exception safety guarantee. The function takes care to allocate new storage for the copy before changing the state of the object. Only after the allocation succeeds does the function proceed to change the state of the object. In addition, by copying the array to the newly allocated storage before deallocating the existing array, the function avoids the test for self-assignment, thus improving which improves the performance of the code in the common case.
...
Code that is not exception safe typically leads to resource leaks, causes the program to be left in an inconsistent or unexpected state, and ultimately results in in undefined behavior at some point after the first exception is thrown.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ERR56-CPP | highHigh | likelyLikely | highHigh | P9 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
| 4075, 4076 |
Other Languages
TO DO
Bibliography
...
CWE-460: Improper Cleanup on Thrown Exception |
...
CWE-703: Failure to Handle Exceptional Conditions |
...
...
-754: Improper Check for Unusual or Exceptional Conditions |
...
CWE-755: Improper Handling of Exceptional Conditions | |
[ISO/IEC 14882-2003] | |
[MISRA 08] | Rule 15-3-2 |
...
Rule 15-3-4 |
[Sutter 00] |
...
Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions | |
[Sutter 01] |
...
More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions |
...