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 before 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
.
在绑定参数之前是否完全评估了所有参数?在这种情况下,std :: move是无害的,因为它只是产生一个引用数字的xvalue。或者,一旦评估,每个单独的参数是否可以立即绑定到其参数?在这种情况下,数字[0]可能会导致未定义的行为,因为数字可能已经被移动到vec中。
1 个解决方案
#1
10
On §1.9/15 we're told that:
在§1.9/ 15我们被告知:
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:
关于§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.
我在最终草案中找不到任何其他相关文字。由于这没有明确定义参数评估与参数初始化之间的关系之前的顺序,因此它们未被排序,并且std :: move不是无害的。
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);
#1
10
On §1.9/15 we're told that:
在§1.9/ 15我们被告知:
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:
关于§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.
我在最终草案中找不到任何其他相关文字。由于这没有明确定义参数评估与参数初始化之间的关系之前的顺序,因此它们未被排序,并且std :: move不是无害的。
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);