参数评估后是不是对参数绑定进行排序?

Posted

技术标签:

【中文标题】参数评估后是不是对参数绑定进行排序?【英文标题】:Is parameter binding sequenced after argument evaluation?参数评估后是否对参数绑定进行排序? 【发布时间】:2011-11-05 22:51:41 【问题描述】:

假设我有以下功能:

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 是无害的,因为它只产生一个引用 numbers 的 xvalue。或者每个单独的参数是否可以在评估后立即绑定到它的参数?在这种情况下,numbers[0] 可能会导致未定义的行为,因为 numbers 可能已经被移动到 vec

【问题讨论】:

numbers[0] 不会抛出,对吧?你的意思是numbers.at(0),对吧? 在调试模式下,numbers[0] 可以做所有它想做的健全性检查。 @R。 Martinho:我冒昧地编辑了这个问题。我不认为“导致异常”是问题的重要部分,而是在评估所有参数之前是否可以移动对象。 @FredOverflow:这是未定义的行为,它可以在任何模式(调试/发布)下造成任何影响。符合规范的实现可能会决定抛出异常、断言或任何其他行为。 【参考方案1】:

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

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

第 5.2.2/4 节:

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

我在最终草案中找不到任何其他相关文本。由于这没有明确定义参数评估和参数初始化之间的 sequenced before 关系,因此它们是unsequenced 并且std::move 并非无害。 p>

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

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

【讨论】:

以上是关于参数评估后是不是对参数绑定进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

iVerilog 中的 MUX:无法绑定参数/无法评估 genvar 表达式错误

OracleCommand SQL 参数绑定

GIN下关于参数的多次绑定问题

list参数绑定

SpringMVC参数绑定的原理

Common Lisp宏中的词法绑定