Rule A12-8-3 (required, implementation, partially automated)

Moved-from object shall not be read-accessed.

Rationale

Except in rare circumstances, an object will be left in an unspecified state after its values has been moved into another object. Accessing data members of such object may result in abnormal behavior and portability concerns.

Exception

It is permitted to access internals of a moved-from object if it is guaranteed to be left in a well-specified state. The following Standard Template Library functions are guaranteed to leave the moved-from object in a well-specified state: move construction, move assignment, “converting” move construction and “converting” move assignment of std::unique_ptr type move construction, move assignment, “converting” move construction, “converting” move assignment of std::shared_ptr type move construction and move assignment from a std::unique_ptr of std::shared_ptr type move construction, move assignment, “converting” move construction and “converting” move assignment of std::weak_ptr type std::move() of std::basic_ios type move constructor and move assignment of std::basic_filebuf type move constructor and move assignment of std::thread type move constructor and move assignment of std::unique_lock type move constructor and move assignment of std::shared_lock type move constructor and move assignment of std::promise type

move constructor and move assignment of std::future type move construction, move assignment, “converting” move construction and “converting” move assignment of std::shared_future type move constructor and move assignment of std::packaged_task type

Example

// $Id: A12-8-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <iostream>
#include <memory>
#include <string>
void F1()
{
std::string s1{"string"};
std::string s2{std::move(s1)};
// ...
std::cout << s1 << "\n"; // Non-compliant - s1 does not contain "string"
// value after move operation
}
void F2()

{
std::unique_ptr<std::int32_t> ptr1 = std::make_unique<std::int32_t>(0);
std::unique_ptr<std::int32_t> ptr2{std::move(ptr1)};
std::cout << ptr1.get() << std::endl; // Compliant by exception - move
// construction of std::unique_ptr
// leaves moved-from object in a
// well-specified state

}

See also

SEI CERT C++ [10]: EXP63-CPP Do not rely on the value of a moved-from object.