-2

I have a code. The code prints 1236 (g++ 7.5.0)

Does the output depend on the compiler? (e.g. output can be 3216)

#include <bits/stdc++.h>


using namespace std;


int foo(int& x) {
    std::cout << ++x; 
    return x;
}


int main() {
    int i = 0;
    cout << foo(i) + foo(i) + foo(i) << endl; // 1236
}
mascai
  • 1,373
  • 1
  • 9
  • 30
  • 2
    already the first line is non portable C++. Others compiler may not even compile this – 463035818_is_not_an_ai Jan 28 '23 at 17:04
  • 2
    [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Thomas Weller Jan 28 '23 at 17:05
  • 2
    [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Thomas Weller Jan 28 '23 at 17:05
  • 1
    @463035818_is_not_a_number "Don't". Other compilers *don't* compile this. No "may" about it. MSVC in particular. – Casey Jan 28 '23 at 17:06
  • @Casey what I said. Other compilers may compile it or may not compile it. It is non standard – 463035818_is_not_an_ai Jan 28 '23 at 17:08
  • 1
    Regarding `foo(i) + foo(i) + foo(i)` part specifically; I believe it's portable. The order of evaluation of the three `foo` calls is unspecified, but the code is arranged so that it produces the same outcome regardless of that order. The three calls are equivalent, so it doesn't matter which one goes first, or second. – Igor Tandetnik Jan 28 '23 at 17:10
  • @Casey Nitpick: there is more than one compiler that can compile this (GCC and Clang when it uses libstdc++). So 463035818_is_not_a_number is correct. – HolyBlackCat Jan 28 '23 at 18:12

1 Answers1

7

No, the output does not depend on the compiler (modulo the bits/stdc++.h nonsense). The order in which the three calls foo(i) are evaluated is unspecified, but that doesn't affect the output: function calls are not interleaved, so some call will increment i to 1, print that, and return it (as a copy), then one of the other two will assign, print, and return 2, then the last will do 3, and their return values will always sum to 6.

Note that if foo returned int&, the last output might be any digit 6–9, since the implementation might not choose to read i for the addition immediately upon return. The behavior would still be defined, though, since those reads would be indeterminately sequenced with respect to any write.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76