In
foo(v).bar(std::move(v))
There are no guarantees(See comments, pre C++17) that the v
in foo(v)
will be evaluated before the std::move(v)
in bar(std::move(v))
The clang-tidy docs comes with an example of this.
Unsequenced moves, uses, and reinitializations
In many cases, C++ does not make any guarantees about the order in which sub-expressions of a statement are evaluated. This means that in code like the following, it is not guaranteed whether the use will happen before or after the move:
void f(int i, std::vector v);
std::vector v = { 1, 2, 3 };
f(v[1], std::move(v));
In this kind of situation, the check will note that the use and move are unsequenced.
The check will also take sequencing rules into account when reinitializations occur in the same statement as moves or uses. A reinitialization is only considered to reinitialize a variable if it is guaranteed to be evaluated after the move and before the use.