Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would i+=l compile, where i is int and l is long?

I spotted Java's +=, -=, *=, /= compound assignment operators (good question :)), but it had a part that I don't quite understand. Borrowing from that question:

int i = 5;
long l = 8;

Then i = i + l; will not compile but i += l; will compile fine.

The accepted answer to the linked question states that:

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.

which gives that i += l; is the same as i = (int)((i) + (l)); with the exception that i is only evaluated once.

A long may be (IIRC even is guaranteed to be) longer than an int, and thus can hold a much greater range of values.

Given that this situation can very easily cause data loss due to necessary narrowing conversion at some point during execution of the statement (either r-value expression evaluation, or assignment), why is i += l; not a compile-time error or at least warning?

like image 479
user Avatar asked Jan 03 '12 14:01

user


People also ask

What is long L?

long l = 2147483648; //CE: value is treated as int but out of range. Here we need to put suffix as L to treat the literal 2147483648 as long type by java compiler.

What is 12L in C?

12L is a long integer, and so the constant has a long type, but it can always be represented by an int . C guarantees that an int must be equal or less than the length of a long. By default the constant 12 is an int -- any constant that requires a long will automatically be long.

What does L after number mean in java?

The L suffix tells the compiler that we have a long number literal. Java byte , short , int and long types are used do represent fixed precision numbers.

How do you specify long in java?

To specify a numeric literal as a long instead of an int , add an L (for long ) to the end of the literal. Either capital or lowercase will work, but a lowercase 'l' can easily be confused with the numeral '1', especially in monospace fonts.


2 Answers

Basically, because i += l is compiled as if it were written i = (int) (i + l). There are similar "surprises" when adding int values to byte and char variables -- the assignment operator works while the plain addition operator does not.

like image 149
Ernest Friedman-Hill Avatar answered Nov 08 '22 16:11

Ernest Friedman-Hill


Given that this situation can very easily cause data loss due to necessary narrowing conversion at some point during execution of the statement (either r-value expression evaluation, or assignment), why is i += l; not a compile-time error or at least warning?

It probably should be, as you said, either a compile-time error or at least warning. Most books and tutorials that I'm aware of introduce x += y; as shorthand for x = x + y;. I honestly don't know of any that make the distinction called out in section 15.26.2 Compound Assignment Operators of the JLS except one.

In chapter 2 (puzzle 9) of Java Puzzlers: Traps, Pitfalls, and Corner Cases the authors (Joshua Bloch & Neal Gafter) ask you to provide declarations for x and i such that this is a legal statement:

x += i;

and this is not:

x = x + i;

There are lots of solutions, including the first two lines of code that you posted in your question. The authors warn against using compound assignment operators on variables of types byte, short, and char, and recommend that when using these operators on variables of type int you should make sure that the RHS expression is not a long, float, or double.

They conclude with the following observation (emphasis mine):

In summary, compound assignment operators silently generate a cast. If the type of the result of the computation is wider than that of the variable, the generated cast is a dangerous narrowing cast. Such casts can silently discard precision or magnitude. For language designers, it is probably a mistake for compound assignment operators to generate invisible casts; compound assignments where the variable has a narrower type than the result of the computation should probably be illegal.

like image 43
Bill the Lizard Avatar answered Nov 08 '22 15:11

Bill the Lizard