1

Say for example I have a long statement like

cout << findCurrent() << "," << findLowest() << "," << findHighest() << "," << findThird()<<"\n";

would findCurrent() be run before findLowest() like logic dictates?

M.M
  • 138,810
  • 21
  • 208
  • 365
iZeusify
  • 140
  • 1
  • 7
  • 4
    https://stackoverflow.com/questions/8704455/how-does-couts-operator-work-with-regard-to-operator-precedence , https://stackoverflow.com/questions/5214611/unexpected-order-of-evaluation-compiler-bug , https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Mitch Wheat May 16 '18 at 01:44
  • @MitchWheat those links have little to do with this question (there is no UB here) – M.M May 16 '18 at 01:48
  • The order of evaluation is unspecified: https://stackoverflow.com/questions/7718508/order-of-evaluation-of-arguments-using-stdcout?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Mitch Wheat May 16 '18 at 01:51
  • 1
    @Goran Flegar I heard that there were changes in C++17. Didnt know what changed though. According to M.M it is left to right. That question was on an old version of c++. – iZeusify May 16 '18 at 02:00
  • @MitchWheat but you didn't flag it as duplicate - this was an automated comment from flagging it. – gflegar May 16 '18 at 02:03
  • @iZeusify the question didn't specify C++17, now that it does I'll remove the flag. – gflegar May 16 '18 at 02:03

2 Answers2

7

Since C++17 the functions are guaranteed to be called left-to-right, i.e. findCurrent() is called first, then findLowest() and so on.

C++17 Standard references: [expr.shift]/4 (referring to the expression E1 << E2):

The expression E1 is sequenced before the expression E2.

[over.match.oper]/2: (describing overloaded operators)

the operands are sequenced in the order prescribed for the built-in operator.

[intro.execution]/15:

An expression X is said to be sequenced before an expression Y if every value computation and every side effect associated with the expression X is sequenced before every value computation and every side effect associated with the expression Y.

Link to cppreference summary


Prior to C++17 the order of function calls was unspecified, meaning that they may be called in any order (and this order does not need to be the same on repeated invocations).

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 2
    Funny how it took decades to get a simple sentence into the Standard that fixes all doubts. – DeiDei May 16 '18 at 02:00
  • 2
    @DeiDei For a long time it was argued that leaving it unspecified allows the optimizer to generate faster code by using the fastest call order; however evidence didn't really back that up, and in a famous incident, they built the Windows NT kernel against the new evaluation order and it actually sped it up – M.M May 16 '18 at 02:01
  • @M.M I found the source of that: [the original proposal](http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0145r1.pdf) for the change in evaluation order. It says that some tests were faster but others were slower, so no difference on balance. (If changing it had made it faster, that would've been evidence that evaluation order actually does matter for optimisation.) – Arthur Tacca Dec 08 '20 at 10:15
1

Before C++17, the order of evaluation is unspecified.

As of C++17, it's required to be evaluated left-to-right. See M.M's answer for standard quotation.

iBug
  • 35,554
  • 7
  • 89
  • 134