Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Warning
titleWork In Progress

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. (See ERR51-CPP. Handle all exceptions.)

Because Since exceptions introduce code paths into a program that wouldn't 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 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:from most to least desired.

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.)

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.)

Basic Exception Safety

None

Code that provides neither the strong nor

the

basic exception safety guarantee is not exception safe.

No Exception Safety

Code that guarantees strong exception safety also guarantees basic exception safety.

Because all exceptions thrown in an application must be handled, in compliance with ERR50-CPP. Do not abruptly terminate the program, it is critical that thrown exceptions do not leave the program in an indeterminate state where invariants are violated. That is, the program must provide basic exception safety for all invariants and may choose to provide strong exception safety for some invariants. Whether exception handling is used to control the termination of the program or to recover from an exceptional situation, a violated invariant leaves the program in a state where graceful continued execution is likely to introduce security vulnerabilities. Thus, code that provides no exception safety guarantee is unsafe and must be considered defective.

Non-Compliant Code Example

TO DO

...

bgColor#FFcccc

Compliant Solution

TO DO

Anchor
No Exception Safety
No Exception Safety

Noncompliant Code Example (No Exception Safety)

The following noncompliant code example shows a flawed copy assignment operator. 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 function deallocates array and assigns the element counter, nElems, before allocating a new block of memory for the copy. As a result, if 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, such an object is in an indeterminate state and any operation on it, including its destruction, results in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <cstring>
 
class IntArray {
  int *array;
  std::size_t nElems;
public:
  // ...

  ~IntArray() {
    delete[] array;
  }

 
  IntArray(const IntArray& that); // nontrivial copy constructor
  IntArray& operator=(const IntArray &rhs) {
    if (this != &rhs) {
      delete[] array;
      array = nullptr;
      nElems = rhs.nElems;
      if (nElems) {
        array = new int[nElems];
        std::memcpy(array, rhs.array, nElems * sizeof(*array));
      }
    }
    return *this;
  }

  // ...
};

Anchor
Strong Exception Safety
Strong Exception Safety

Compliant Solution (Strong Exception Safety)

In this compliant solution, the copy assignment operator provides the strong exception safety guarantee. The function allocates 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, which improves the performance of the code in the common case [Sutter 2004].

#ccccff
Code Block
bgColor#ccccFF
langcpp
#include <cstring>
 
class IntArray {
  int *array;
  std::size_t nElems;
public:
  // ...

  ~IntArray() {
    delete[] array;
  }

  IntArray(const IntArray& that); // nontrivial copy constructor

  IntArray& operator=(const IntArray &rhs) {
    int *tmp = nullptr;
    if (rhs.nElems) {
      tmp = new int[rhs.nElems];
      std::memcpy(tmp, rhs.array, rhs.nElems * sizeof(*array));
    }
    delete[] array;
    array = tmp;
    nElems = rhs.nElems;
    return *this;
  }

  // ...
};
Code Block
bgColor

Risk Assessment

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 undefined in undefined behavior at some point after the first exception is thrown.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR39-CPP

3 (high)

3 (likely)

3 (high)

P27

L1

Other Languages

TO DO

Bibliography

Wiki Markup
\[[CWE|AA. Bibliography#CWE]\] [CWE-460|http://cwe.mitre.org/data/definitions/460.html]: Improper Cleanup on Thrown Exception
\[[ISO/IEC 14882-2003|AA. Bibliography#ISO/IEC 14882-2003]\]
\[[MISRA 08|AA. Bibliography#MISRA 08]\] Rule 15-3-2, 15-3-4
\[[Sutter 00|AA. Bibliography#Sutter 00]\] Sutter, Herb. _Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions_
\[[Sutter 01|AA. Bibliography#Sutter 01]\] Sutter, Herb. _More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions_

ERR56-CPP

High

Likely

High

P9

L2

Automated Detection

Tool

Version

Checker

Description

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

ALLOC.LEAK

Leak

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C++4075, C++4076
LDRA tool suite
Include Page
LDRA_V
LDRA_V

527 S, 56 D, 71 D

Partially implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_CPP-ERR56-a
CERT_CPP-ERR56-b

Always catch exceptions
Do not leave 'catch' blocks empty
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: ERR56-CPPChecks for exceptions violating class invariant (rule fully covered).
PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V565V1023, V5002

Related Vulnerabilities

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

Related Guidelines

SEI CERT C++ Coding StandardERR51-CPP. Handle all exceptions
MITRE CWE

CWE-703, Failure to Handle Exceptional Conditions
CWE-754, Improper Check for Unusual or Exceptional Conditions
CWE-755, Improper Handling of Exceptional Conditions

Bibliography

[ISO/IEC 14882-2014]Clause 15, "Exception Handling"
[Stroustrup 2001]
[Sutter 2000]
[Sutter 2001]
[Sutter 2004]55. "Prefer the canonical form of assignment."


...

Image Added Image Added Image Added ERR14-CPP. Do not allow an exception class's methods to throw exceptions      12. Exceptions and Error Handling (ERR)      ERR31-CPP. Don't redefine errno