Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In Java, the following code does not compile:

int val = 1;
short shortVal = val;  // Incompatible types

Anyone know why Java chooses to complain about this assignment, instead of simply truncating, when an integer × integer is also likely to overflow?

To illustrate:

int val = 46340;
int result = val * val;                    // 2147395600
System.out.println(result);
int overflowVal = 46341;
int result2 = overflowVal * overflowVal;   // -2147479015
System.out.println("Quietly overflowed: " + result2);
share|improve this question
1  
Because complaining in the first case doesn't cause infinite amounts of frustration? –  Anton Barkovsky Dec 20 '11 at 19:18
add comment

5 Answers

up vote 11 down vote accepted

In the first case, the compiler knows that you're facing a potential loss of precision, so it can stop you. In the second case the overflow happens during a runtime calculation - though your example trivialy causes an overflow, there is no way for the compiler to check such occurrences in general case so it doesn't.

share|improve this answer
1  
It's still only a potential loss... in either case. Yes, it can't stop you in the second case, but that's not a real reason why it should, in the first. –  NickC Dec 20 '11 at 21:02
2  
@Renesis, rockets have literally blown up in the sky due to simple precision problems like in your first example. The compiler has it right. Use a typecast if you want it to act differently. –  Stargazer712 Dec 21 '11 at 14:16
add comment

It'd be weird if int * int = long. Internally, that's exactly what (x86) processors do anyways, but it would make for some rather interesting programming challenges. Occasional overflow is easier to handle than auto-recasting everytime you do an operation!

So, in short, int to short is prevented because it's easy to prevent. Int/int overflow is allowed rather than upcasting because upcasting would bring about even more ugliness. Looks like a design decision based on the lesser of multiple evils.

share|improve this answer
    
If I were designing a language, I would specify that operations on normal integral numeric types would generally be performed as if they were performed on the largest signed integral type, with the caveat that explicit disambiguating typecasts may be needed in some contexts involving function overloading. The compile-time analysis would not be hard; some code might generate slightly less efficient code than expected, but unexpected overflows are bad and should be trapped. Programmers wanting "wrapping" behavior should use wrapping integer types. –  supercat Jan 17 at 0:24
add comment

The int to short assignment is a type error in the "computer sciency" definition of the term. The intent is to prevent programmers from accidentally doing something bad (like assigning something into a short that can't be represented in a short). Multiplying an int and a short is also technically a type error in the "computer sciency" definition of the term, but there is less of a chance for mischief here since the type system gets to decide what type to make the result of an int x short operation. Most people wouldn't like to cast their shorts to ints every time math is done with a short and and int, so compilers will do this for you.

In a nutshell: With assignment, the types are constrained, there's no room to budge. With arithmetic, the type system gets to decide what the resulting type should be, and chooses a compatible type in this case (int) and inserts any required casts for you.

share|improve this answer
add comment

Type mismatch in a calculation is not really an issue, since the result of the calculation is still definable even for operands of different bit sizes. The issue of arithmetic overflow at runtime is more general, as it can happen even in calculations among same bit size operands, and there clearly is no point to have the compiler warn us about the possibility that we may have an overflow every time we increment an integer. So, the question boils down to why does java not offer something like the 'checked' keyword of C# so as to offer the possibility of catching arithmetic overflow at runtime. But that would be the subject of a different question.

share|improve this answer
add comment

Int to Short is a type conversion, and java requires explicit casts even where the type conversion could be deduced automatically.

Java's lax treatment of incorrect results from integer arithmetic is a separate matter. It's a very good question why integer overflow doesn't cause a runtime exception.

share|improve this answer
1  
Could be a concession to speed but more likely it's just because that's the way C did it, they tried to follow patterns from C wherever it made sense. –  Bill K Dec 20 '11 at 20:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.