0

As shown in the example below, I am expecting that the compiler should add an implicit move constructor and should move the data present in obj1 into obj2 and either make the obj1 blank or have some indeterminate state.

#include <iostream> #include <memory> #include <mutex> using namespace std; class Demo { public: int val = 3; }; int main() { Demo obj1; cout << "before move obj1.val :" << obj1.val << std::endl; Demo obj2(std::move(obj1)); //Expecting obj1.val moves into obj2.val and becomes zero etc. cout << "after move obj1.val :" << obj1.val << std::endl; cout << "after move obj2.val :" << obj2.val << std::endl; return 0; } 

//output:

before move obj1.val :3 after move obj1.val :3 after move obj2.val :3 
9
  • Because that wastes time. Commented Jan 22, 2023 at 4:52
  • 1
    A move copy/assignment is only required to leave the object moved from in a valid state, no more. Commented Jan 22, 2023 at 4:52
  • 1
    "either make the obj1 blank or have some indeterminate state" Isn't 3 a valid, indeterminate state? Commented Jan 22, 2023 at 5:10
  • 1
    "Indeterminate state" means just that. It does not mean "zeroed". It does not mean "set to some randomized value". If an object retains its original value, that is a perfectly acceptable outcome. Commented Jan 22, 2023 at 5:11
  • 1
    "either make the obj1 blank or have some indeterminate state" -- in other words, make obj1.val equal to zero or to any integer value that fits in an int. From my perspective, you have failed to show that this does not happen. Perhaps you should include your expected output, in addition to the actual output? Commented Jan 22, 2023 at 6:09

1 Answer 1

4

This is a common misunderstanding about what move semantics means in C++.

It does not mean "under penalty of extreme torture, pain and anguish you must take everything from the moved-from object, and put it into the moved-to object, and leave nothing but a vast wasteland and flaming wreckage in the moved-from object, once the move operation finishes".

What it does mean is "make the moved-to object be identical to the moved-from object in the most efficient way possible, transfer the state of the moved-from object to the moved-to object, and you are allowed to mess up the moved-from object's contents as much as you want, as long as the transfer is as efficient as possible". This is what a move means in C++ (1).

Leaving the moved-from object's state unchanged, at the conclusion of the move operation, is a perfectly valid result. It is common to observe this when moving small std::strings in C++ implementations that employ short string optimizations.

And in case of natural integer and numeric types, this is the only practical result you can possibly expect. Not taking any extra step to set the moved-from bytes to the contents of a random number generator, or something, is the least amount amount of work: none.

(1) Formally, the C++ standard defines this as the effects of a move on C++ library types, in practice the definition is also adopted by all other C++ libraries.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.