如果我们有三个函数(foo,bar和baz),就像这样......
foo(bar(), baz())
C ++标准是否保证在baz之前评估条形码?
答案 0 :(得分:89)
不,没有这样的保证。根据C ++标准,它是未定义的。
Bjarne Stroustrup在“C ++编程语言”第3版第6.2.2节中也明确地说过,有一些推理:
可以生成更好的代码 没有表达限制 评估顺序
虽然从技术上讲,这是指同一部分的早期部分,它表示表达式部分的评估顺序也是不确定的,即
int x = f(2) + g(3); // undefined whether f() or g() is called first
答案 1 :(得分:20)
bar()和baz()没有指定的顺序 - 标准说的唯一的事情就是在调用foo()之前它们都将被评估。从C ++标准,第5.2.2 / 8节:
参数的评估顺序 没有具体说明。
答案 2 :(得分:17)
从[5.2.2]函数调用,
参数的评估顺序未指定。参数表达式求值的所有副作用在输入函数之前生效。
因此,无法保证bar()
将在baz()
之前运行,只有在bar()
之前调用baz()
和foo
。
同样请注意[5]表达式:
除非另有说明,否则
&&
和||
]的特殊规则,各个运算符的操作数和各个表达式的子表达式的评估顺序以及副作用发生的顺序是未指定的。
所以,即使您询问bar()
是否会在baz()
中foo(bar() + baz())
之前运行,订单仍未指定。
答案 3 :(得分:9)
C ++ 17指定在C ++ 17之前未指定的运算符的求值顺序。请参阅问题What are the evaluation order guarantees introduced by C++17?但请注意您的表达
foo(bar(), baz())
仍未指定评估顺序。
答案 4 :(得分:2)
在C ++ 11中,相关文本可以在8.3.6 Default arguments/9(强调我的)
中找到每次调用函数时都会计算默认参数。 函数参数的评估顺序未指定。因此,函数的参数不应在默认参数中使用,即使它们未被评估。
C ++ 14标准也使用相同的词汇,可以在the same section下找到。
答案 5 :(得分:0)
正如其他人已经指出的那样,该标准没有就这一特定情景的评估顺序提供任何指导。然后将此评估顺序留给编译器,编译器可能有保证。
重要的是要记住C ++标准实际上是指示编译器构造汇编/机器代码的语言。该标准只是等式的一部分。如果标准不明确或者是特定的实现定义,那么您应该转向编译器并理解它如何将C ++指令转换为真正的机器语言。
因此,如果评估顺序是一项要求,或者至少是重要的,并且不需要交叉编译器兼容,那么请研究一下编译器最终如何将它们组合在一起,您的答案最终可能就在那里。请注意,编译器可能会在将来更改它的方法