8

Is:

x -= y;

equivalent to:

x = x - y;
dukevin
  • 22,384
  • 36
  • 82
  • 111

3 Answers3

37

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

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • 1
    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 Mar 10 '10 at 05:00
  • 14
    Are we here to tell people what they want to hear, or to pursue excellent and accurate technical knowledge? – polygenelubricants Mar 10 '10 at 05:18
  • 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 Mar 10 '10 at 05:37
  • @Martin, @Chuck, I've added some clarifications to the subtleties. – polygenelubricants Mar 10 '10 at 09:33
  • 1
    Had to run it to believe it. Thanks and +1 – Amarghosh Mar 10 '10 at 14:29
  • 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 May 08 '10 at 08:58
  • @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 May 08 '10 at 09:12
5

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

Chuck
  • 234,037
  • 30
  • 302
  • 389
2

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
  • 19,673
  • 4
  • 43
  • 72