The following program shows two problematic (but technically valid) uses of std::move()
. Is it possible to get a compile warning about these with LLVM? I have noticed that there is diagnostic for some other contexts where std::move
is redundant.
I compiled this with bcc32c version 5.0.2 (based on LLVM 5.0.2) and received no warnings.
#include <vector>
int main() {
const std::vector<int> a = {1, 2, 3};
std::vector<int> b = {3, 4, 5};
std::vector<int> c = std::move(a); // std::move from const
std::vector<int> d = std::move(b);
std::vector<int> e = b; // used after std::move
}
std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
std::move itself does "nothing" - it has zero side effects. It just signals to the compiler that the programmer doesn't care what happens to that object any more. i.e. it gives permission to other parts of the software to move from the object, but it doesn't require that it be moved.
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.
std::move in C++Moves the elements in the range [first,last] into the range beginning at result. The value of the elements in the [first,last] is transferred to the elements pointed by result. After the call, the elements in the range [first,last] are left in an unspecified but valid state.
clang-tidy's bugprone-use-after-move
checker supports this kind of diagnostic:
bugprone-use-after-move
Warns if an object is used after it has been moved, for example:
std::string str = "Hello, world!\n"; std::vector<std::string> messages; messages.emplace_back(std::move(str)); std::cout << str;
The last line will trigger a warning that str is used after it has been moved.
[...]
Use
Any occurrence of the moved variable that is not a reinitialization (see below) is considered to be a use.
[...]
If multiple uses occur after a move, only the first of these is flagged.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With