Suppose I have the following function:
void foo(std::vector<int> vec, int n);
If I call the function like this:
std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);
Are all the arguments completely evaluated befo开发者_JS百科re being bound to their parameters? In that case, the std::move
is harmless, because it simply yields an xvalue referring to numbers
. Or can each individual argument immediately be bound to its parameter as soon as it is evaluated? In that case, numbers[0]
could cause undefined behavior, because numbers
could already have been moved into vec
.
On §1.9/15 we're told that:
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. (...)
And on §5.2.2/4:
(...) The initialization and destruction of each parameter occurs within the context of the calling function. (...)
I couldn't find any other relevant text in the final draft. Since this does not explicitly define a sequenced before relationship between evaluation of arguments and the initialization of the parameters, they're unsequenced and the std::move
is not harmless.
A solution to this issue would be to force a sequence with a temporary variable:
std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
int num = numbers[0];
foo(std::move(numbers), num);
精彩评论