6

Consider the following program:

#include <iostream>

int f() {
    std::cout << 0;
    return 1;
}

int main() {
    std::cout << f();
}

It outputs the following text:

01

Is this guaranteed by the standard though? The following things happen (not neccesarly in order)

  • (A) side effects of std::cout (not observable here)
  • (B) value evaluation of std::cout
  • (C) side effects of f() (print 0)
  • (D) value evaluation of f()
  • (E) side effects of the << operator (print 1)
  • (F) value evaluation of the << operator

Reading the order of evaluation rules on cppreference I managed to find the following:

  • Rule 2) says that (B) and (D) happen before (F).
  • Rule 19) (C++17) says that (A) and (B) happen before (C) and (D)

I could imagine, that there is a rule that says the side effects of a function happen before the return of a value, that means (C) happens before (D). I am not a hundred percent sure about where this is explicitely written down though. Maybe rule 11)?

That leaves (E) which I could not find a sequence rule for. Rule 2) explicitely excludes side effects from the sequence order, so:

  • What are the rules for (E)?
  • Is this guaranteed to be sequenced after the other observable side effect (C)?

Note:
I stumbled on this problem when discussing this recent question, which is related but more about sequencing of chained << operators. I wanted to ask for this specific question in a more condensed form and with more of my own reasoning behind it.

Botje
  • 26,269
  • 3
  • 31
  • 41
Jakob Stark
  • 3,346
  • 6
  • 22
  • I asked a similar question 4 years ago: https://stackoverflow.com/q/51784836/3684343 Yes, it is guaranteed by the standard, first `cout` will be evaluated, then `f()` will be evaluated (prints 0) and then `cout << 1` will be evaluated. – mch Jun 01 '22 at 10:17
  • f() is a subexpression used as an argument in a function call to operator<<(cout, f()), so the rules you're looking for are the ones about function calls. "3)" in the cppreference page. – Cubbi Jun 01 '22 at 14:49
  • 1
    @Cubbi no, the rule for `<<` apply here (left before right), not the rule for function arguments (unspecified which one first): https://stackoverflow.com/questions/38501587/what-are-the-evaluation-order-guarantees-introduced-by-c17 and https://stackoverflow.com/a/46408392/3684343 – mch Jun 02 '22 at 06:29
  • 1
    @mch my comment was not about argument vs argument (which indeed became l-to-r for overloaded shifts in C++17, but also doesn't make a difference in this example), but about arguments vs body – Cubbi Jun 02 '22 at 21:24

0 Answers0