C++17中函数参数求值:unsequenced还是indeterminately sequenced?
先给你明确结论:在C++17标准里,函数参数的初始化(包括所有相关的值计算和副作用)是不确定顺序(indeterminately sequenced),而非无顺序(unsequenced)。
你之前参考的[intro.execution.17]是表达式求值的通用规则,但函数调用属于标准专门做了例外规定的场景。C++17的[expr.call]条款里有明确说明:
The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.
这里的"indeterminately sequenced"是什么意思呢?简单说就是:每个参数的求值过程都会完整地在另一个参数的求值之前或之后完成,但具体哪个先哪个后是编译器说了算的。和unsequenced的核心区别在于,indeterminately sequenced不会出现两个参数的求值操作重叠,这就避免了unsequenced可能引发的未定义行为(比如同一内存位置的无顺序副作用)。
至于你搜索"indeterminately"字符串没关联到函数参数的问题,大概率是因为这条规则藏在[expr.call]的细节里,不是以单独的条款标题出现的。你直接去翻[expr.call]的内容就能找到这条规定。
另外,cppreference上的描述是完全正确的,它精准对应了C++17标准里的这条规则,所以你看到的cppreference内容和标准是一致的,只是你之前没找到标准里的对应条款而已。
总结一下:函数参数的求值并不适用[intro.execution.17]里的通用规则,因为[expr.call]已经专门规定了它们是indeterminately sequenced。这既保证了参数求值不会重叠引发未定义行为,又给编译器留下了优化的空间。
内容的提问来源于stack exchange,提问作者alexeykuzmin0

