Alex Rivera | Logout

Why doesn't compound assignment in Java catch overflow problems?

Asked 2011-03-30T01:21:41.077
13

To my shock, it turns out that the following code will compile without even warnings:

public void test()
{
    int value = 2000000000;
    long increment = 1000000000;
    value += increment;
}

Whereas this gives a compile-time error, as you would expect:

public void test()
{
    int value = 2000000000;
    long increment = 1000000000;
    value = value + increment;
}

I checked it up and indeed, the JLS (section 15.26.2) has this to say:

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.

This seems ridiculous to me. Why did they feel the need to explicitly cast here? It seems that automatic type conversion would have handled the widening anyway, and automatically narrowing like this is pretty much guaranteed to result in integer overflow.

Edit
Report

1 Answer

2

The compound assignment operators are specified by the JLS (15.26.2) as follows:

"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."

In this case E1 is of type int E2 is of type long, and op is +. So this is equivalent to:

value = (int)(value + increment);

The addition of an int and a long gives a long that is then cast back to an int before assignment. That is all fine, hence no compilation error.

The difference between this and the simple assignment (i.e. value = value + increment;), is that the simple assignment doesn't have a typecast.


OK, so why did they define it this way?

I think that the reason is to make examples like this work:

    byte b = ...
    b += 1;

Without the typecast, b += 1 would be a compilation error and you'd need to write it as:

    b += (byte) 1;
answered 2011-03-30T02:21:40.730

Your Answer