Reputation: 61
When evaluating a Boolean expression in java, I find myself a bit bewildered by short circuit evaluation and pre-fix increment operators. Consider the following:
int e=20;
int f=25;
if(++e>21 || ++e>21 && f>30){
System.out.println("Hi");
}
System.out.println(e);
I understand that if ++e were greater than 21, the rest of the IF statement would skip over (due to short circuit eval). But in this case, it doesn't, as the first part is not true, so we move on to the AND statement. At this point, is e still 20? Or during the short circuit eval, did it go up to 21?
Well, I am assuming at this point, we evaluate the AND statement (as we normally do before OR), we add 1 to e, which I assume becomes 21 now? It is false, and therefore the entire AND statement is false.
Do we, at this point, go BACK and do the OR statement? Since it comes after AND? Shouldn't e be pumped up to 22 now? And since it's an OR statement, it should come out to TRUE OR FALSE, which should be TRUE, and "Hi" should appear on the screen. But it doesn't.
Weirdly, the value for e is 22 when the code finishes. 22 is the value we needed for the IF statement to be true, but the condition inside didn't run.
I am extremely confused.
Upvotes: 2
Views: 511
Reputation: 720
Let's unwind what short-circuiting actually is!
int e=20;
int f=25;
if((++e>21) || (++e>21 && f>30)){
System.out.println("Hi");
}
System.out.println(e);
So, if that left hand side of the or
condition evaluates to true, we don't need to do anything more, so let's be more explicit about that:
int e=20;
int f=25;
if (++e > 21)
{
System.out.println("Hi");
}
// the or becomes an else if, if the first condition fails then we check the second
else if (++e>21 && f>30)
{
System.out.println("Hi");
}
System.out.println(e);
Now, let's be more explicit about when that first increment happens:
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e>21 && f>30)
{
System.out.println("Hi");
}
System.out.println(e);
Again, let's unwind what and
means in terms of short-circuiting
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e > 21) // the and becomes a nested if, first the left must be true before we test the right
{
if (f > 30)
{
System.out.println("Hi");
}
}
System.out.println(e);
And again, let's be explicit about that increment!
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else
{
e += 1;
if (e > 21) // e is now 22, this condition succeeds
{
if (f > 30) // f is not >30, this condition fails!
{
System.out.println("Hi");
}
}
// e is still 22
}
// e is still 22
System.out.println(e);
Hopefully this makes it all clear!
EDIT: Actually, having re-read your question a couple of times, it appears you are getting confused with the precedence of the logical operators. You seem to think that the and
should execute before the or
right? presumably because and
has the higher precedence. All that means, however, is that the implicit brackets go round the and
first like so;
p || q && r == p || (q && r)
You should be able to see that in this form, the outside or
must be evaluated first, before the and
is. We always evaluate left to right!
Upvotes: 7