12

I recently discovered that Java (and Scala) include non-short-circuiting logical operators &, |, and ^. I previously thought these only worked as bitwise operators. While maybe there is an argument for ^, I can't think of very good reasons for using non-short-circuiting logical operators--although sure, I can contrive an example.

Are these operators useful? They seem more likely to cause hard-to-catch bugs.

scala> def foo = {
     |   println("foo")
     |   true
     | }
foo: Boolean

scala> def bar = {
     |   println("bar")
     |   true
     | }
bar: Boolean

scala> foo || bar
foo
res5: Boolean = true

scala> foo | bar
foo
bar
res6: Boolean = true
Frank S. Thomas
  • 4,725
  • 2
  • 28
  • 47
schmmd
  • 18,650
  • 16
  • 58
  • 102
  • 1
    No, the bitwise operators should only be used for bitwise operations, IMHO :) – Niklas B. Mar 02 '12 at 21:41
  • 1
    The only possible answers to this question are specific examples of "non-short-circuiting operators are useful when you don't want short circuiting". So the real question is "when do you not want short circuiting"? – Dan Burton Mar 02 '12 at 22:48

4 Answers4

16

They're useful if the right-hand side is a function with side-effects that you want to execute regardless (e.g. logging). However, I would suggest that that's a bit of a code smell and will certainly be unintuitive to the next guy.

dty
  • 18,795
  • 6
  • 56
  • 82
8

Hmm. I know they can be incredibly useful for optimizing C/C++ code if used carefully. It might apply to Java as well.

The major use in C -- other than actual bit operations -- is to remove a pipeline stall. The short circuit operators require a branch operation. The bitwise operator will compute both sides and removes the chance for a mispredicted branch and the resulting stall.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • I guess you'd have to balance the cost of the stall against the cost of executing code that wouldn't otherwise need to be run/affect the outcome of the program – dty Mar 02 '12 at 21:54
  • @dty: Yes, absolutely. Note the "if used carefully." :-) – Zan Lynx Mar 02 '12 at 21:56
  • 5
    When I was writing Guava's `com.google.common.math`, when the second condition was particularly fast, my benchmarks sometimes indicated that non-short-circuiting operators were faster than short-circuiting operators for this reason. (That said, I wouldn't have made that change if I didn't have very solid, detailed benchmarks.) – Louis Wasserman Mar 02 '12 at 23:10
2

Using the non-short-circuit boolean operators implies that the operands have side effects. If they had no side effects, then the programmer could have used the short-circuit versions with no change in functionality.

In code written in a functional style (which Scala surely encourages but does not require), side effects are an indication that something unusual is going on. Unusual things should be clearly indicated in code, rather than by something as subtle as a non-short-circuit boolean operator.

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

If you are trying to track answers or input for something, and that depends on both sides of your non-short-circuit boolean running.

As an example, say you have:

if(methodA() & methodB()){
    //some code
}

And within the methodB() method some essential code is running. If that was a short circuit code ( && ) and methodA() was false, methodB() would never run.

That is one of the uses I can think of, at least.