C++函数参数中的评估顺序

Cla*_*bel 83 c++ standards

如果我们有这样的三个函数(foo,bar和baz)......

foo(bar(), baz())
Run Code Online (Sandbox Code Playgroud)

C++标准是否保证在baz之前评估条形码?

Eli*_*sky 92

不,没有这样的保证.根据C++标准,它是未定义的.

Bjarne Stroustrup在"C++编程语言"第3版第6.2.2节中也明确地说过,有一些推理:

在没有对表达式评估顺序的限制的情况下,可以生成更好的代码

虽然从技术上讲这是指同一部分的早期部分,它表示表达式部分的评估顺序也是未定义的,即

int x = f(2) + g(3);   // unspecified whether f() or g() is called first
Run Code Online (Sandbox Code Playgroud)

  • @ChrisDodd 由于使用“未定义”与“未指定”这个词而对已接受的答案投反对票,对我来说感觉像是恶意的迂腐……我没有说这是“未定义的行为”,否则“未定义”和“未指定”似乎同义词?无论如何,建议对答案进行编辑将是讨论此问题的更有效的方式 (4认同)
  • 是的,但如果表达式评估顺序是STRICT,那么更好的代码可能是WRITTEN(=更清晰),这通常比代码生成重要得多.请参阅此示例:http://stackoverflow.com/questions/43612592/the-case-where-c-ab-is-not-equal-to-c-ab-b-b1?noredirect=1#comment74274141_43612592那么,斯特劳斯. (3认同)
  • 如果订购很重要,您可以自己进行排序。否则总是会因为一些并不总是(很少?)重要的事情而付出代价。我认为不为不使用的东西付费的政策是大多数 C++ 程序员唯一同意的政策。 (3认同)
  • 它不应该是"未指明的行为"而不是"未定义的"吗? (3认同)

小智 20

bar()和baz()没有指定的顺序 - 标准说的唯一的事情就是在调用foo()之前它们都将被评估.从C++标准,第5.2.2/8节:

参数的评估顺序未指定.

  • 它们在foo()之前被评估的事实至少有点令人放心. (3认同)
  • @BillKotsias 标准还规定函数调用不能重叠(即实现不能运行“bar”的第 1 行,然后运行“baz”的第 1 行,然后运行“bar”的第 2 行,等等),这也很好。:-) (2认同)

Dan*_*ien 17

从[5.2.2]函数调用,

参数的评估顺序未指定.参数表达式求值的所有副作用在输入函数之前生效.

因此,不能保证bar()将之前运行baz(),只bar()baz()会之前被调用foo.

另请注意[5]表达式:

除非另有说明[例如,特殊规则&&||],各个操作员的操作数的评估顺序和个别表达式的子表达式以及副作用的发生顺序是未指定的.

所以即使你在问是否bar()将之前运行baz()foo(bar() + baz()),订单仍然是不确定的.

  • 来自[5.14] Logical AND运算符的"特殊注释"示例:"与`&`不同,`&&`保证从左到右的评估:如果第一个操作数是'false`,则不评估第二个操作数." (4认同)

S.M*_*.M. 10

C++ 17规定了在C++ 17之前未指定的运算符的求值顺序.请参阅问题C++ 17引入的评估顺序保证是什么?但请注意你的表达

foo(bar(), baz())
Run Code Online (Sandbox Code Playgroud)

仍未指定评估顺序.