4
#include <iostream>

int a(int &x) {
    x = -1;
    return x;
}

int main () {
    int x = 5;
    std::cout << a(x) << " " << x << std::endl;
}

Why output is "-1 5"?

PS: compiler is:

i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

PS: compiled without any optimization.

LihO
  • 41,190
  • 11
  • 99
  • 167
Sukhanov Niсkolay
  • 1,298
  • 1
  • 12
  • 26

3 Answers3

15

In this line:

std::cout << a(x) << " " << x << std::endl;

the order of evaluation of a(x) and x is not specified. It's unspecified behaviour what happens, in your case the compiler decided to evaluate x first, a(x) afterwards.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • 4
    It is *undefined behavior*? I think it is *unspecified behavior*. – Nawaz Oct 07 '13 at 18:21
  • @Nawaz Hm, could be unspecified behaviour (§1.3.15) I think. Edited. – Daniel Frey Oct 07 '13 at 18:25
  • This is strange in my opinion because function has worked already. And i hoped that value in the cell in a memory was changed. Maybe somebody can explain me how it can be translate in an asm code? – Sukhanov Niсkolay Oct 07 '13 at 18:26
  • 1
    @SukhanovNiсkolay It is changed, if you look at it *after* this line. The compiler turned this line into `auto tmp1 = x; auto tmp2 = a(x); std::cout << tmp2 << " " << tmp1 << std::endl;` (without the additional sequence points, of course) - which is legal although, as already mentioned, not guaranteed. – Daniel Frey Oct 07 '13 at 18:29
3

The order, in which a(x) and x are being evaluated is unspecified [1]. To make sure that x will not be modified within the same expression (and avoiding unspecified behavior by doing so), you could do:

int x = 5;
int y = a(x);
std::cout << y << " " << x << std::endl;

[1] "Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. " 5 Expressions, §4

LihO
  • 41,190
  • 11
  • 99
  • 167
1

The order of evaluation is unsequenced and hence it is unspecified behavior either a(x) or x could be evaluated first. With respect to the C++ draft standard section 1.9 Program execution paragraph 15 says(emphasis mine):

[...]Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] [...]

and it may even differ between different evaluations and furthmore if we go back to paragraph 13 it says:

[...]If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which.[...]

which explains that this is unspecified behavior.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740