4
int it=9, at=9;

if(it>4 || ++at>10 && it>0)  
{
    System.out.print("stuff");    
}

System.out.print(at);

prints out stuff9 and I want to know why as I thought ++at>10 && it>0 would be evaluated first and thus make at = 10.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Aside from the variable names, this is a good question. I don't see why it's downvoted. – Michael Yaworski May 13 '14 at 00:23
  • 1
    @mikeyaworski - "go before" is not exactly sound terminology for what the OP is asking. And this is all covered in any half decent Java textbook or tutorial. – Stephen C May 13 '14 at 02:27
  • @StephenC A lot of questions can be answered in a book or tutorial. He was using the knowledge that and precedes or, but didn't realize that short-circuiting resulted in unexpected output. That's a fair inquiry I think, regardless of whether or not short-circuiting is in a book. One might still think what he thought with that knowledge too. – Michael Yaworski May 13 '14 at 02:41
  • @mikeyaworski - Now >>you<< are using bad terminology. AND does not "precede" or. AND has a *higher precedence* than OR. But anyway, I'm simply explaining why some people would think this is a bad question. – Stephen C May 13 '14 at 02:55
  • @StephenC Thanks for the correction, although I don't understand why "precede" is incorrect. Still, it's not a good reason to downvote, but I realize you're just pointing it out. – Michael Yaworski May 13 '14 at 03:24
  • possible duplicate of [&& (AND) and || (OR) in IF statements](http://stackoverflow.com/questions/1795808/and-and-or-in-if-statements) – Raedwald May 14 '14 at 07:40

3 Answers3

14

Operator precedence only controls argument grouping; it has no effect on execution order. In almost all cases, the rules of Java say that statements are executed from left to right. The precedence of || and && causes the if control expression to be evaluated as

it>4 || (++at>10 && it>0)

but the higher precedence of && does not mean that the && gets evaluated first. Instead,

it>4

is evaluated, and since it's true, the short-circuit behavior of || means the right-hand side isn't evaluated at all.

user2357112
  • 260,549
  • 28
  • 431
  • 505
9

Your compound expression is equivalent to

if(it>4 || (++at>10 && it>0))  

due to Java operator precedence rules. The operands of || are evaluated left to right, so it>4 is evaluated first, which is true, so the rest of it (the entire && subexpression) doesn't need to be evaluated at all (and so at does not change).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
0

I feel I should add how to actually get your expected output.

Brief explanation: the || operator short-circuits the entire expression, thus the right side not even being evaluated.

But, to not short-circuit and get your expected output, instead of the || operator, just use |, like so:

int a = 9, b = 9;

if(a>4 | ++b>10 && a>0)  
{
    System.out.print("stuff");    
}
System.out.print(b);

The output to that is stuff10

This way, regardless of one side being true or not, they're both still evaluated.

The same thing goes for && and &

Michael Yaworski
  • 13,410
  • 19
  • 69
  • 97