Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM Cost Reform

...

The following Standard Template Library functions are guaranteed to leave the moved-from object in a well-specified state.

TypeFunctionalityMoved-from State
std::unique_ptrMove construction, Move assignment,
"Converting" move construction, "Converting" move assignment
(
Likewise
likewise for std::unique_ptr for array objects with a runtime length)The moved-from object is guaranteed to refer to a null pointer value, per [unique.ptr], paragraph 4 [ISO/IEC 14882-2014].
std::shared_ptr

Move construction, Move assignment,
"Converting" move construction, "Converting" move assignment 

The moved-from object shall be "empty," per [util.smartptr.shared.const], paragraph 22 and [util.smartptr.shared.assign], paragraph 4.
std::shared_ptrMove construction, Move assignment from a std::unique_ptrThe moved-from object is guaranteed to refer to a null pointer value, per [util.smartptr.shared.const], paragraph 29 and [util.smartptr.shared.assign], paragraph 6.
std::weak_ptrMove construction, Move assignment,
"Converting" move construction, "Converting" move assignment 
The moved-from object shall be "empty," per [util.smartptr.weak.const], paragraph 8, and [util.smartptr.weak.assign], paragraph 4.
std::basic_iosmove()The moved-from object is still left in an unspecified state, except that rdbuf() shall return the same value as it returned before the move, and tie() shall return 0, per [basic.ios.members], paragraph 20.
std::basic_filebufMove constructor, Move assignmentThe moved-from object is guaranteed to reference no file; other internal state is also affected, per [filebuf.cons], paragraphs 3 and 4, and [filebuf.assign], paragraph 1.
std::threadMove constructor, Move assignmentThe result from calling get_id() on the moved-from object is guaranteed to remain unchanged; otherwise the object is in an unspecified state, per [thread.thread.constr], paragraph 11 and [thread.thread.assign], paragraph 2.
std::unique_lockMove constructor, Move assignmentThe moved-from object is guaranteed to be in its default state, per [thread.lock.unique.cons], paragraphs 21 and 23.
std::shared_lockMove constructor, Move assignmentThe moved-from object is guaranteed to be in its default state, per [thread.lock.shared.cons], paragraphs 21 and 23.
std::promiseMove constructor, Move assignmentThe moved-from object is guaranteed not to have any shared state, per [futures.promise], paragraphs 6 and 8.
std::futureMove constructor, Move assignmentCalling valid() on the moved-from object is guaranteed to return false, per [futures.unique_future], paragraphs 8 and 11.
std::shared_futureMove constructor, Move assignment,
"Converting" move constructor, "Converting" move assignment 
Calling valid() on the moved-from object is guaranteed to return false, per [futures.shared_future], paragraphs 8 and 11.
std::packaged_taskMove constructor, Move assignmentThe moved-from object is guaranteed not to have any shared state, per [future.task.members], paragraphs 7 and 8.

Several generic standard template library (STL) algorithms, such as std::remove() and std::unique(), remove instances of elements from a container without shrinking the size of the container. Instead, these algorithms return a ForwardIterator to indicate the partition within the container after which elements are no longer valid. The elements in the container that precede the returned iterator are valid elements with specified values; whereas the elements that succeed the returned iterator are valid but have unspecified values. Accessing unspecified values of elements iterated over results in unspecified behavior. Frequently, the erase-remove idiom is used to shrink the size of the container when using these algorithms.

...

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
#include <string>

void g(std::string &&v) {
  std::cout << v << std::endl;
}

void f() {
  std::string s;
  for (unsigned i = 0; i < 10; ++i) {
    s.append(1, static_cast<char>('0' + i));
    g(std::move(s));
  }
}

...

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <string>

void g(std::string &&v) {
  std::cout << v << std::endl;
}

void f() {
  for (unsigned i = 0; i < 10; ++i) {
    std::string s(1, static_cast<char>('0' + i));
    g(std::move(s));
  }
}

...

The state of a moved-from object is generally valid, but unspecified. Relying on unspecified values can lead to abnormal program termination as well as data integrity violations.

Rule

Severity

Likelihood

Detectable

Remediation Cost

Repairable

Priority

Level

EXP63-CPP

Medium

Probable

Medium

Yes

No

P8

L2

Automated Detection

Tool

Version

Checker

Description

 

  

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.MEM.NPD
LANG.MEM.UVAR

Null Pointer Dereference
Uninitialized Variable

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF4701, DF4702, DF4703


Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-EXP63-a

Do not rely on the value of a moved-from object

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: EXP63-CPPChecks for read operations that reads the value of a moved-from object (rule fully covered)
PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V1030
 

Related Vulnerabilities

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

Related Guidelines

  


Bibliography

[ISO/IEC 14882-2014]

Subclause 17.6.5.15, "Moved-from State of Library Types"
Subclause 20.8.1, "Class Template unique_ptr"
Subclause 20.8.2, "Shared-Ownership Pointers"
Subclause 27.5.5, "Class Template basic_ios"
Subclause 27.9.1, "File Streams"
Subclause 30.3.1, "Class thread"
Subclause 30.4.2, "Locks"
Subclause 30.6, "Futures"

...


...

 Image Modified