参数绑定是否在参数求值后排序?

发布于 2024-12-01 16:01:35 字数 429 浏览 2 评论 0原文

假设我有以下函数:

void foo(std::vector<int> vec, int n);

如果我像这样调用该函数:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);

所有参数在绑定到其参数之前是否已完全评估?在这种情况下,std::move 是无害的,因为它只是产生一个引用数字的 xvalue。或者每个单独的参数在被求值后是否可以立即绑定到它的参数?在这种情况下,numbers[0] 可能会导致未定义的行为,因为 numbers 可能已被移至 vec 中。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴情 2024-12-08 16:01:35

在 §1.9/15 中,我们被告知:

调用函数时(无论函数是否内联),每个值的计算和副作用
与任何参数表达式或指定被调用函数的后缀表达式相关联的是
在执行被调用函数体中的每个表达式或语句之前排序。 (...)

以及第 5.2.2/4 节:

(...) 每个参数的初始化和销毁​​发生在
调用函数。 (...)

我在最终草案中找不到任何其他相关文本。由于这没有明确定义参数求值和参数初始化之间的先序关系,因此它们未排序并且std::move代码>并非无害。

此问题的解决方案是强制使用临时变量的序列:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
int num = numbers[0];
foo(std::move(numbers), num);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文