-1

Given that x is initialised to 0 before each statement on the left executes, the result is the value displayed on the right:

(++x + ++x) + ++x == 7
++x + (++x + ++x) == 9
++x + ++x + ++x   == 7

Why does the first statement result in 7 and the second statement result in 9 ???

Why is the result of the first statement the same as the third statement ???

murungu
  • 2,090
  • 4
  • 21
  • 45

1 Answers1

3

Well it is undefined behaviour... it is likely that the compiler will write code that looks like this.

(++x + ++x) + ++x == 7
x = 0
x++ => 1 (x)
x++ => 2 (x)
r = 2 + 2
x++ => 3 (x)
r + x = 7

And this

++x + (++x + ++x) == 9

x++ => 1  x + (++x + ++x)
x++ => 2  x + (x + ++x)
x++ => 3  x + (x + x)
//You'll have x + (x + x) where x is 3
// Now
r = 3 + 3
x + r = 9

Annnd all this is valid for the compiler you're currently using. Other compilers could be smart enough to return the same results some don't. It might even depend on the level of optimization and it all stand down to undefined behaviour.

In conclusion, don't write code that looks like this. I'm pretty sure that your compiler is outputting some warnings about this.

To explain a bit more what it's happening is that you're modifying a register in place. Before it can do operations, it has to evaluate the "++". So one might think that you end up with:

1 + 2 + 3 => 5

But in reality, since the ++ isn't supposed to allocate new memory, it will increase the value in place. The order from left to right might be forced using parenthesis. So in one case, it will increase 2 times then a third time when it sums r + x and the version with parenthesis forces every ++ from left to right and then sum x + r. But since it's undefined behaviour. It doesn't really mean anything. Just don't do that.

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99
  • You might like to add **what** provokes the undefined behaviour. – alk Mar 01 '14 at 16:21
  • The evaluations seem inconsistent to me... I think it could make some more sense if the second evaluation started off with the first `++x` inside the parenthesis instead. – Utkan Gezer Mar 01 '14 at 16:30
  • Any variable must not be modified more than once without intervening sequence points. It is perfectly valid for the compiler to emit code that deletes all your files if you do it (although it would be a bit extreme). – Vatine Mar 01 '14 at 16:55
  • @ThoAppelsin if the second evaluation did evaluate the `++` inside the parenthesis first, it would give `7` too. It might make more sense to do it like that but it would be still wrong. – Loïc Faure-Lacroix Mar 01 '14 at 16:55
  • @LoïcFaure-Lacroix Evaluate the `++`s inside the parenthesis, then without evaluating the result of the parenthesis, get back and evaluate the `++` outside the parenthesis, `x == 3` now and then `r = x`, then evaluate the parenthesis and add it to `r`, `r == 9` then... I don't know why it would ever do it like this, but the way it has been put right now for two cases are inconsistent. – Utkan Gezer Mar 01 '14 at 17:24
  • @ThoAppelsin because evaluation happens **left to right**. If it starts evaluating the parenthesis it should return when the parenthesis are evaluated completely. Not evaluate all the `++,--` then evaluate all the `*,/,%..` then `-,+...`. It's consistent in **left to right**. – Loïc Faure-Lacroix Mar 01 '14 at 18:11