The definitions of +=
seem to be the same in both Java and C++, however, they perform differently.
Consider the following code in C++:
#include <iostream>
int n;
int f(int x) {
n += x;
return x;
}
int main() {
n = 0;
n = n + f(3);
std::cout<<n<<" ";
n = 0;
n += f(3);
std::cout<<n<<" ";
n = 0;
n = f(3) + n;
std::cout<<n<<std::endl;
}
This outputs: 3 6 6
Similar code in Java outputs: 3 3 6
, here is the code for reference.
static int n;
public static void main(String[] args) {
n = 0;
n = n + f(3);
System.out.println(n);
n = 0;
n += f(3);
System.out.println(n);
n = 0;
n = f(3) + n;
System.out.println(n);
}
public static int f(int x) {
n += x;
return x;
}
Looking at the documentation for C++ and Java, they write similar definitions:
C++:
E1 op= E2 (where E1 is a modifiable lvalue expression and E2 is an rvalue expression or a braced-init-list (since C++11)) is exactly the same as the behavior of the expression E1 = E1 op E2, except that the expression E1 is evaluated only once and that it behaves as a single operation with respect to indeterminately-sequenced function calls
Java:
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.
Out of curiosity, I checked this in Python, and it has the same output as Java. Of course, writing code like this is extremely bad practice, but I'm still curious for an explanation.
I suspect that the ordering of the way variables get evaluated is different for +=
in different languages, but I don't know exactly how. What in the definitions am I missing, and how are compound assignment operators evaluated?