 
                            ...
For example, in C++03, std::auto_ptr had the following copy operation signatures [ISO/IEC 14882-2003]:
| Copy constructor | auto_ptr(auto_ptr &A); | 
| Copy assignment | auto_ptr& operator=(auto_ptr &A); | 
Both copy construction and copy assignment would mutate the source argument, A, by effectively calling this->reset(A.release()). However, this invalidated assumptions made by standard library algorithms such as std::sort(), which may need to make a copy of an object for later comparisons [Hinnant 05]. Consider the following implementation of std::sort() that implements the quick sort algorithm.
...
In this compliant solution, the copy operations for A no longer mutate the source operand, ensuring that the vector contains equivalent copies of obj. Instead, A has been given move operations that perform the mutation when it is safe to do so.
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| #include <algorithm>
#include <vector>
class A {
  int m;
  
public:
  A() : m(0) {}
  explicit A(int m) : m(m) {}
  
  A(const A &other) : m(other.m) {}
  A(A &&other) : m(other.m) { other.m = 0; }
  
  A& operator=(const A &other) {
    if (&other != this) {
      m = other.m;
    }
    return *this;
  }
 
  A& operator=(A &&other) {
    m = other.m;
    other.m = 0;
    return *this;
  }
  
  int get_m() const { return m; }
};
void f() {
  std::vector<A> v{10};
  A obj(12);
  std::fill(v.begin(), v.end(), obj);
} | 
Exceptions
OOP58-CPP-EX0: Reference counting, and implementations such as std::shared_ptr<> constitute an exception to this rule. Any copy or assignment operation of a reference-counted object requires the reference count to be incremented. The semantics of reference counting are well-understood, and it can be argued that the reference count is not a salient part of the shared_pointer object.
Risk Assessment
Copy operations that mutate the source operand or global state can lead to unexpected program behavior. Using such a type in a Standard Template Library container or algorithm can also lead to undefined behavior.
| Rule | Severity | Likelihood | Detectable | 
|---|
| Repairable | Priority | Level | 
|---|---|---|
| OOP58-CPP | Low | Likely | 
| Yes | No | 
| P6 | L2 | 
Automated Detection
| Tool | Version | Checker | Description | 
|---|
| CodeSonar | 
 | LANG.FUNCS.COPINC | Copy Operation Parameter Is Not const | ||||||
| Helix QAC | 
 | C++4075 | |||||||
| Klocwork | 
 | CERT.OOP.COPY_MUTATES | |||||||
| Parasoft C/C++test | 
 | CERT_CPP-OOP58-a | Copy operations must not mutate the source object | ||||||
| Polyspace Bug Finder | 
 | CERT C++: OOP58-CPP | Checks for copy operation modifying source operand (rule partially covered) | 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
| [ISO/IEC 14882-2014] | Subclause 12.8, "Copying and Moving Class Objects" Table 21, "CopyConstructible Requirements" Table 23, "CopyAssignable Requirements" | 
| [ISO/IEC 14882-2003] | 
| [Hinnant 2005] | "Rvalue Reference Recommendations for Chapter 20" | 
...
...