views:

280

answers:

3

Super quick question to refresh my mind:

Is:

x -= y;

equivalent to:

x = x - y;

Thanks!

+6  A: 

Yes, it is. This syntax is the same in most C-derived languages.

Chuck
Thanks, just making sure it wasn't:x = y - x
Kevin Duke
+31  A: 

No, they are NOT equivalent the way you expressed them.

short x = 0, y = 0;
x -= y;    // This compiles fine!
x = x - y; // This doesn't compile!!!
              // "Type mismatch: cannot convert from int to short"

The problem with the third line is that - performs what is called "numeric promotion" (JLS 5.6) of the short operands, and results in an int value, which cannot simply be assigned to a short without a cast. Compound assignment operators contain a hidden cast!

The exact equivalence is laid out in JLS 15.26.2 Compound Assignment Operators:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

So to clarify some of the subtleties:

  • Compound assignment expression doesn't reorder the operands
    • Left hand side stays on the left, right hand side stays on the right
  • Both operands are fully-parenthesized to ensure op has the lowest precedence
    • int x = 5; x *= 2 + 1; // x == 15, not 11
  • There is a hidden cast
    • int i = 0; i += 3.14159; // this compiles fine!
  • The left hand side is only evaluated once
    • arr[i++] += 5; // this only increments i once

Java also has *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^= and |=. The last 3 are also defined for booleans (JLS 15.22.2 Boolean Logical Operators).

Related questions

polygenelubricants
Who's downvoting/un-upvoting? Try the code out for yourself! Equivalence is a strictly defined concept, and strictly speaking, the two expressions are NOT equivalent (or else the code would compile).
polygenelubricants
Are we here to tell people what they want to hear, or to pursue excellent and accurate technical knowledge?
polygenelubricants
Don't know why anybody would downvote this. It's good information. I still think my answer is more directly what the question is about (as Martin said), but I don't see why anyone would object to this answer.
Chuck
@Martin, @Chuck, I've added some clarifications to the subtleties.
polygenelubricants
Upvote for the effort put into this
Charlie Somerville
Had to run it to believe it. Thanks and +1
Amarghosh
In real life I must say that I hardly ever find anyone using short's, they tend to default to selecting int as a number type.So this is an anomaly, but the compiler's default choice of int for the return type of the subtraction operation seems to be a good default choice. By substituting short as the type for comparitive purposes you have highlighted an anomaly that is academically interesting, but practically irrelevent for most intensive purposes. However, I don't believe that your answer deserves a downvote.
crowne
@crowne: There's a book called `Java Puzzlers: Traps, Pitfalls, and Corner Cases`; this case was covered in the book. Maybe this book is "irrelevent for most intensive purposes" because "in real life" you personally have never come across these traps, pitfalls, and corner cases, but if you ask me, I think it's a great book and I wish more people read it.
polygenelubricants
+2  A: 

Not exactly. The reason it was introduced in C was to allow the programmer to do some optimizations the compiler couldn't. For example:

A[i] += 4

used to be compiled much better than

A[i] = A[i] + 4

by the compilers of the time.

And, if "x" has side effects, e.g "x++" then it is wildly different.

Richard Pennington
In Java, how can "x" have side effects?
Thilo
I believe he mean to refer to the left hand side in general, hence the quotes. See my 4th bullet point about a non-trivial left-hand side that matters when evaluated twice.
polygenelubricants