-1

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
Mangy
  • 119
  • 6
  • Because that wastes time. – HolyBlackCat Jan 22 '23 at 04:52
  • 1
    A move copy/assignment is only required to leave the object moved from in a valid state, no more. – wohlstad Jan 22 '23 at 04:52
  • @Wohlstad : sorry i couldn't get your answer. Could you explore more with some example? – Mangy Jan 22 '23 at 04:57
  • Mangy I recommend you to find a good book (e.g. from here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and learn about move semantics. It's hard to cover this subject in a SO comment. In a nut shell: when you move from an object there's no explicit requirement about the state of that object, other than being valid. E.g. there's no requirement to zero it. You can see @SamVarshavchik's answer for some more info. – wohlstad Jan 22 '23 at 05:02
  • 1
    "either make the `obj1` blank or have some indeterminate state" Isn't 3 a valid, indeterminate state? – Thomas Sablik Jan 22 '23 at 05: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. – printf Jan 22 '23 at 05:11
  • Move operations just do whatever the move assignments/ctors code impliments for the type of each variable in the object. If they don't have them, like built in types, they don't do anything beyond copy. – doug Jan 22 '23 at 05:30
  • The _title_ of this question bothers me, because the accompanying post clearly shows that obj2 clearly has been updated with the same data as obj1. Perhaps we need to define what is meant by “move”? – Dúthomhas Jan 22 '23 at 05:55
  • 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? – JaMiT Jan 22 '23 at 06:09

1 Answers1

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148