1

Ok so I had a weird issue in java and I'm pretty sure this is common to most languages but it was the first time I've encountered something like this. Assume you have two methods.

private boolean foo(int param){ /*some arbitrary stuff*/ }
private boolean bar(int param){ /*some arbitrary stuff*/ }

Each of these methods expect parameters and based on the contents of the parameters they return a true or false based on whether or not something happened. Now I'm going to put them to work.

if(foo(21) || bar(321)){

    //do some other stuff

}

The idea here is to run foo() and bar() and if either of them return true do the other stuff.

It looked fine, it compiled, but when I ran the code things were funky. It was almost as if bar() was not running whenever foo() returned true. So realizing the logical possibility of that I rewrote my code.

boolean a = foo(21);
boolean b = bar(321);

if(a || b){

    //do some other stuff

}

and that fixed my issue. My question is does anyone know why this happens or if there are other practices to ensure the entirety of a conditional is evaluated should it need to?

rfoo
  • 1,160
  • 1
  • 12
  • 27
  • This a good example of why it is good to avoid side-effects in expressions :) Note than you can use `bool | bool`, which does not short-circuit. But see above. – user2246674 Sep 29 '13 at 23:42
  • 1
    The reason it's important to have operators like `||` is that so you can write stuff like `if (index >= myArray.length || myArray[index] == 0)`. If the right part were always evaluated, even if the index were too large, you couldn't do this--it would get an out-of-bounds exception, even though we already know from the left part that the whole expression will be `true`. (I used to program in Pascal, which doesn't have short circuits, and it's really a pain to work around.) It's not just array indexes. There are **lots** of uses. – ajb Sep 29 '13 at 23:51
  • @ajb Yeah upon learning about this right now I've already cut out maybe 16 lines of code from just one of my classes. This has been a very enlightening discovery. – rfoo Sep 29 '13 at 23:55

2 Answers2

3

Your problem is with short-circuiting. Using || causes the operation to short-circuit once one true value is found. You can instead use | to evaluate both expressions, even if the first is true. Same is true with && and & when it comes to evaluating to false.

if (true || someMethod()) { }

In this statement above, the someMethod() will never be called because true short-circuits the result.

if (true | someMethod()) { }

In this, the someMethod() will be called even though it being true or false is irrelevant to the evaluation of the boolean expression as a whole. See here for more information on short-circuiting in Java: Java logical operator short-circuiting

Community
  • 1
  • 1
Kon
  • 10,702
  • 6
  • 41
  • 58
  • Excellent answer and thanks for all of the extra information! I can't believe this is the first time I've ever encountered this. I'll accept this answer when I'm allowed to. – rfoo Sep 29 '13 at 23:43
0

This is called short-circuiting.

Logical operators will stop evaluating their operands once they know what the result will be.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964