1

When I run this program I get strange output 1132. Can somebody explan me why is 1132?

//main.cpp
#include <iostream>
using namespace std;

int f1(int &a){return a++;}
int f2(int &a){return ++a;}

int main(){
    int x, y;
    int *px, *py;
    x = 1;
    y = 2;
    px = &x;
    py = &y;
    cout << f1(*px) << *px << f2(*py) << *py << "\n";

    return 0;
}
Nemanja I.
  • 19
  • 1
  • There is no guarantee that the expressions are evaluated left to right. – Shloim Sep 08 '16 at 12:18
  • 1233 for me. You're invoking undefined behaviour. – Richard Hodges Sep 08 '16 at 12:19
  • It is totally depand on compiler. In your case expression is evaluated from right to left . :) – Undefined Behaviour Sep 08 '16 at 12:20
  • @Shloim: really? In this case, with `operator<<(std::ostream, T)`, I'd have expected this to be `((cout << f1(*px)) << *px)` etc., in which case a left-to-right evaluation would be guaranteed? – rainer Sep 08 '16 at 12:20
  • 1
    The `<<` is evaluated left to right, but the expressions between each pair of `<<` were evaluated right-to-left – Shloim Sep 08 '16 at 12:21
  • Here's a similar question: http://stackoverflow.com/questions/25669493/c-why-does-llvm-evaluate-printf-left-to-right-when-gcc-evaluates-right-to-left – Shloim Sep 08 '16 at 12:23
  • @Shloim: Of course, thanks! I forgot that while this guarantees the order of the calls to `<<`, it doesn't introduce any sequence points. – rainer Sep 08 '16 at 12:25
  • Well, anyone who writes code like this gets what they deserve. This does not seem like a "practical programming problem" to me. – Cody Gray - on strike Sep 08 '16 at 12:37
  • #offtopic: you should really use `endl` instead oh `'\n'` – Shloim Sep 08 '16 at 19:09

2 Answers2

2

The order of evaluation in your case was right-to-left.

Note that there is no guarantee for a left-to-right evaluation.

So order was:

  1. *py

  2. f2(*py)

  3. *px

  4. f1(*px)

Only then the << operators ran (and were evaluated left-to-right as expected)

Shloim
  • 5,281
  • 21
  • 36
1

In this line:

cout << f1(*px) << *px << f2(*py) << *py << "\n";

The compiler is free to evaluate each expression in any order (even though the order of execution of operator<< is left to right).

The expressions are:

f1(*px)
f2(*py)
*px
*py

The evaluation order may be any one of the npr(4,4) permutations.

npr(4,4) = 4! / (4-4)! = 24

Do you feel lucky?

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142