3

I am puzzled by the following:

#include <iostream>

int main()
{
  bool a = true;
  int nb = 1;
  int nb2 = 2;
  a ? nb++, nb2++ : nb--, nb2--;
  std::cout << " (nb,nb2) = (" << nb << "," << nb2 << ")";
}

Result:

(nb,nb2) = (2,2) 

Why is nb2 not equal to 3?

statquant
  • 13,672
  • 21
  • 91
  • 162
  • a) don't use comma operator unless you strictly need it (because *it's evil*), b) don't use ternary to produce side effects - use ternary to get a conditional *value* only. –  Aug 02 '16 at 15:42
  • @NathanOliver: the interesting question is: why does this compile without any warnings ? – Paul R Aug 02 '16 at 15:42
  • @NathanOliver Yeah, I actually jumped the gun on this one. I retracted the close vote but it seems it doesn't remove the associated comment. – Borgleader Aug 02 '16 at 15:43
  • @Borgleader: You can just delete the comment if you like (but I think somebody else voted to close). – Keith Thompson Aug 02 '16 at 15:44
  • I don't think the last `,` is participating where you think it is. You seem to think this is `a ? (nb++, nb2++) : (nb--, nb2--);`. In reality, it is `(a ? (nb++, nb2++) : nb--), nb2--;` – WhozCraig Aug 02 '16 at 15:44
  • 3
    @PaulR What would be the warning? This does not do what you think it does? – NathanOliver Aug 02 '16 at 15:44
  • 1
    The comma operator has the lowest precedence of any operator. The LHS of the comma expression is `a ? nb++, nb2++ : nb--`; the RHS is `nb2--`. – Keith Thompson Aug 02 '16 at 15:45
  • @NathanOliver: I wasn't actually suggesting it *should* give a warning - it just looks so wrong that it was initially surprising (to me at least) that it even compiled. – Paul R Aug 02 '16 at 15:48
  • 1
    Incidentally, you don't (and can't) have multiple statements within an expression. You have multiple *expressions* within an expression. – Keith Thompson Aug 02 '16 at 15:48
  • @KeithThompson Should I reopen and close this as a dupe of http://stackoverflow.com/questions/12136156/whats-the-precedence-of-comma-operator-inside-conditional-operator-in-c to get rid of the dupe link to http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points? – NathanOliver Aug 02 '16 at 15:53

3 Answers3

11

Because of operators priority. Your expression evaluates as

((a) ? (nb++, nb2++) : nb--), nb2--;

Operator , (comma) is the last thing to process. And this example would not compile at all but

The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized.

See C++ Operator Precedence for details.

Dmitriy Zapevalov
  • 1,357
  • 8
  • 13
4

use paranthesis:

a ? (nb++, nb2++) : (nb--, nb2--);

reason: lexical analysis

LiorA
  • 441
  • 3
  • 13
4

It's expected behaviour.

Your expression is understood by the compiler as:

((a) ? (nb++, nb2++) : nb--), nb2--;

For more details see:

Community
  • 1
  • 1
Nemanja Trifunovic
  • 3,017
  • 1
  • 17
  • 20