1

OK so obviously this question might sound dumb for more experienced people, but, for the following lines the result I get is 0:

int x = 2,
y = -2;

cout << (x++ - y && (--x + y));

I understand it means that either one of these two expressions equals 0, but how? As far as I understand, this should be (3 && -1)?

Also, a little subquestion: when does x++ exactly take effect? On the next occurance of x within the same expression, after the left-shift operator within the same line, or in the next statement?

Thank you!

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
Armino
  • 129
  • 1
  • 1
  • 11
  • 2
    Looks like undefined behavior with the order that `x++` and `--x` will get executed. – scohe001 Jan 26 '18 at 19:29
  • 1
    UB for sure, but as an aside most coders would always do `((x++ - y) && (--x + y))` just to be unambiguous about the desired precedence behavior. Makes not difference here tho – pm100 Jan 26 '18 at 19:33
  • Did you read the [FAQ](https://stackoverflow.com/tags/c%2b%2b/info) already what [not to ask](http://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior)? –  Jan 26 '18 at 19:34
  • 4
    I don't believe this is UB. The left part of `operator&&` is necessarily evaluated completely, including all side effects, before the right side. This is because `operator&&` is short circuited for fundamental arithmetic types. This doesn't seem to be a "`i++ + ++i`" question. – François Andrieux Jan 26 '18 at 19:34
  • 2
    After you've evaluated the left part, `x == 3`. So when you evaluated the right part, `--x + y` is `2 + (-2)` which is `0`. I get `4 && 0`. – François Andrieux Jan 26 '18 at 19:42
  • If you aren't on it already @FrançoisAndrieux please write up an answer. The comments above suggest this deserves formal treatment, notice, and some staying power. – user4581301 Jan 26 '18 at 19:46
  • If you ever write such code, you will be damned to eternity in hell debugging COBOL programs. – Carey Gregory Jan 26 '18 at 20:00

1 Answers1

4

As far as I understand, this should be (3 && -1)?

you understand wrong:

first left side is fully evaluated, as it is necessary for short circuit evaluation with logical and (details can be found here)

x++ - y == 4 // as result of x++ == 2 so (2-(-2)), after that x == 3

result is true so right side is evaluated:

--x + y ==  0 // as result of --x == 2 so (2+(-2)), after that x == 2

result on the right is false so result of and is false as well which printed by std::ostream as 0

Note: short circuit evaluation of logical or and and operations make such code valid (making them sequenced) but you better avoid such questionable expressions. For example simple replacing logical and to binary would make it UB.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • 1
    You should mention that the `&&` short-circuits, so it forces the LHS and RHS to be evaluated sequentially. With an operator that doesn't short-circuit, evaluating `x++` and `++x` within the same expression can result in undefined behavior. – Keith Thompson Jan 26 '18 at 20:08
  • @KeithThompson sure, implicitly I mentioned that by ("result is true so right side is evaluated"), but it would not harm to mention that explicitly. – Slava Jan 26 '18 at 20:55
  • @Slava `after that x == 2` is incorrectly placed (even though it's CORRECT) – Mohammad Kanan Jan 26 '18 at 20:57
  • @MohammadKanan why so? – Slava Jan 26 '18 at 20:59
  • @Slava precisely: `--x + y == 0 after that x == 2, (2 + (-2))` – Mohammad Kanan Jan 26 '18 at 21:01
  • @MohammadKanan your variant can be confusing even more, the thing is you cannot say when `x` becomes 2 until operations sequenced, that the reason for UB. You only know that `x` would be 2 after expression ends and result of `--x` is 2 as well. The same for the first, x == 3 after that and result of `x++` is 2. It is wrong way to look on result of expressions `--x` or `x++` as current value of x. – Slava Jan 26 '18 at 21:05
  • @Slava, as --x gets evaluated first , yes its confusing in any place – Mohammad Kanan Jan 26 '18 at 21:11
  • 1
    @MohammadKanan changed it, it should be clear now I think – Slava Jan 26 '18 at 21:11
  • @Slava agree now – Mohammad Kanan Jan 26 '18 at 21:16
  • I understand now. I was actually also suspicious, if x++ changes the value after the statement, or after the &&. But I guess it happens after &&. – Armino Jan 26 '18 at 21:56