如果我们有三个函数(foo,bar和baz),它们的组合如下...
C++标准有没有保证在baz之前bar会被评估?
foo(bar(), baz())
C++标准有没有保证在baz之前bar会被评估?
foo(bar(), baz())
没有这种保证。根据C++标准,这是未指定的。
Bjarne Stroustrup在《C++程序设计语言》第三版6.2.2节中明确表示了这一点,并进行了一些推理:
在表达式求值顺序没有限制的情况下,可以生成更好的代码
尽管技术上这是指同一部分中较早的一个部分,该部分指出表达式的各个部分的求值顺序也是未指定的,即
int x = f(2) + g(3); // unspecified whether f() or g() is called first
来自[5.2.2]函数调用:
参数的求值顺序是未指定的。所有参数表达式的副作用在进入函数之前都会生效。
因此,不能保证bar()
在baz()
之前运行,只能确保在foo
之前调用bar()
和baz()
。
还需要注意来自[5]表达式的:
除了特殊说明(例如
&&
和||
的特殊规则),个别运算符和表达式子表达式的求值顺序以及副作用发生的顺序均未指定。
因此,即使您问foo(bar()+baz())
中的bar()
是否会先于baz()
运行,其顺序仍然未指定。
&
不同,&&
保证从左到右进行求值:如果第一个操作数为 false
,则不会对第二个操作数进行求值。” - Daniel Trebbien参数求值顺序是未指定的。
bar
的第1行,然后是 baz
的第1行,接着是 bar
的第2行等),这也很不错。 :-) - melpomene正如其他人已经指出的那样,标准并没有针对这种情况提供任何关于评估顺序的指导。评估顺序留给编译器处理,而编译器可能会有保证。
重要的是要记住,C++标准实际上是一种指导编译器构建汇编/机器代码的语言。标准只是方程式的一部分。当标准存在歧义或特别是实现定义时,您应该向编译器寻求帮助,并了解它如何将C++指令转换为真正的机器语言。
因此,如果评估顺序是要求,或至少很重要,并且跨编译器兼容性不是要求,请探究您的编译器最终如何将其组合在一起,您的答案可能就在那里。请注意,编译器将来可能会改变其方法。