Java vs C – Why i+=i++ Expression Differs

c++java

I know about the prefix and posfix operation… the difference between ++i and i++ and so.

But I think I'm missing something here. Below you can find the code:

package test;

public class Test
{
    public static void main (String[] args)
    {
        int i=0;

        i+=i++;
        System.out.println(i); // Prints 0

        i = i + (i++);
        System.out.println(i); // Prints 0

        i = i + (i+1);
        System.out.println(i); // Prints 1

    }
}

So the output is:

0
0
1

I tried the same code in C:

#include <stdio.h>
#include <string.h>

main()
{
    int i=0;

    i+=i++;

    printf("%d", i);   // prints 1

    i = i + (i++);
    printf("%d", i);   // prints 3

    i = i + (i+1);
    printf("%d", i);   // prints 7
}

and the output was:

1
3
7

Why i+=i++ doesn't increment i while the same code in C it increments the values?

Best Answer

Java

In Java, the expression has a well-defined meaning. The specification for the compound assignment operators says:

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.

...

At run time, the expression is evaluated in one of two ways. If the left-hand operand expression is not an array access expression, then four steps are required:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

So

i += i++;

is equivalent to

i = i + i++;

Because the value of the left-hand side is saved at the start, and then added to the value of right hand side, and because expression evaluation in Java is left-to-right, the modification of i caused by i++ is overwritten by the subsequent assignment.

All this means that

i += i++;

is equivalent to

i += i;

C

In C the expression

i += i++;

has undefined behavior. And so anything might happen when you execute this code. Which means that you cannot predict what value i will have after the statement completes.

And so it is entirely to be expected that the output from your C program differs from the output from your Java program.