Getting an error, or at least a warning, when using a variable that has been std::move'ed elsewhere
Is there no way to tell the compiler to give me an error (or warning) if I accidentally use the variable after I have moved it?
The answer is "no, there is no way" (to the best of my knowledge at least, no currently available compiler offers such an option, and for a good reason - see below).
Even if that was possible at all, why would you expect a warning, or even worse an error, to be given in this case? First of all, moving from an integer is not any different than copying it.
Secondly, for most types, assigning a moved-from object of that type is a perfectly legal operation; this is always true of fundamental types like int
, and it is definitely true of std::vector
, although it might not be true of other types.
In general, whether or not assigning a moved-from object is legal depends on the particular post-conditions of the move operation for that type and on the preconditions of the assignment operator (the assignment operator for types of the Standard Library have no preconditions on the left-hand side argument). This is something a compiler cannot check in the general case.
Therefore, if you were to:
- Move from an object for which the move assignment or move constructor places the moved-from object in an unspecified state (that's the case for
std::vector
), and then; - Invoke any function with preconditions on the state of that object (and that's not the case for the assignment to an
std::vector
);
That would certainly be bad. On the other hand, the compiler does not have a way to perform a semantic analysis of your program and find out whether this is the case:
A x, y;
...
if (complicatedCondition())
{
y = move(x);
}
foo(x); // Did I move from x? And if so, is it safe to call foo()?
Moreover, don't forget that the philosophy of C++ is to give you power and (most often) design guidelines, but "lets you shoot your feet" if you are really trying to do that.
There are dangerous, even meaningless things that you can do in C++ (will your compiler give you a warning, or an error, if you try to delete
the same pointer twice?), but the language itself won't prevent you from doing them, under the assumption that you really, really know what you are doing.
//do some things, but I gotta be careful I don't do anything to vec
Clarification: You need to be careful that you don't do anything to vec
that requires a precondition. You can do anything with vec
that does not require any preconditions. For example you can assign vec
a new value. You can call vec.clear()
. You can call vec.size()
. But do not call vec.pop_back()
because that member function has a precondition.