Showing posts with label compound assignment. Show all posts
Showing posts with label compound assignment. Show all posts

Sunday, September 4, 2011

The pitfalls of compound assignment operators

Compound assignment operators

You may well know, that in Java (assuming x and y are int variables), instead of writing
    x = x + y;
you can use
    x += y;

The shortcut form is called compound assignment operator and it exists for a lot of operators. They seem harmless enough at first sight.

Now look at this:
    int x = 5, y = 3;
    x *= y + 1;
    System.out.println(x);
You may think that the second line is equivalent to x = x * y + 1, but it is not. It is equivalent to x = x * (y + 1). Therefore x becomes 5 * (3 + 1), i.e. 20.

Short circuit evaluation

Short circuit evaluation describes the fact, that in Java (and many other languages) a boolean expression is only evaluated as long as its final result is not yet known.
    boolean result = true && foo(); // foo gets called
vs.
    boolean result = false && foo(); // foo gets not called
You can (and should) use that to your advantage: Cheap operations to the left, expensive ones to the right (in case of &&, it is the other way round for ||). It also common to use short circuit evaluation for precondition checking:
    boolean result = x != null && x.getMyBool();
If x is really null, we must not call the getMyBool method as it would throw a NullPointerException.

The misleading &= operator

Back to compound assignment operators, there is a &= operator. At first sight, it looks like you could abbreviate
    keep = keep && foo();
by
    keep &= foo();
But, alas, you loose short circuit evaluation, because that really means
    keep = keep & foo();
And the & operator has no short circuit evaluation.

This can be detrimental to the performance of your code, e.g. in cases like this:
   keep &= expensiveOperation1(); 
   keep &= expensiveOperation2(); 
   keep &= expensiveOperation3(); 
   keep &= expensiveOperation4(); 
Or outright fatal, if an operation must not be called
   Object x = null;
   boolean keep = x != null;
   keep &= x.toString().isEmpty();
And there is no &&= compound assignment operator. 

Conclusion

It makes me wonder whether the comfort of saving a few keystrokes and having slightly more compact code to read outweighs these pitfalls and the increased complexity of the language.