Win a copy of Murach's Java Programming this week in the Beginning Java forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

why does java compile literal numbers added and assigned to a short, but not variable integers  RSS feed

 
donald patrick
Greenhorn
Posts: 1
Chrome Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
short x = 10;
short y = 3;
short z = x * y;  //DOES NOT COMPILE.  Reason says: "because x and y are automatically promoted to int.  And then setting a short variable to an int is a compile error.

However,
short a = 10 * 3;  //DOES COMPILE???  Why? exactly.  Documentation says "literals are all interpreted as integers".  So, 10 and 3 are integers.  Yet, for "some" reason that line compiles?

Any comprehensive explanation is appreciated,
donald
 
Henry Wong
author
Sheriff
Posts: 23260
124
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
donald patrick wrote:short x = 10;
short y = 3;
short z = x * y;  //DOES NOT COMPILE.  Reason says: "because x and y are automatically promoted to int.  And then setting a short variable to an int is a compile error.


This explanation isn't totally complete -- although, it is probably complete enough as an answer to a test question "why it doesn't compile?".

To be totally complete, the idea of compile time constant should be mentioned.... meaning there are additional rules based on compile time constants. This code ...

... does compile, because the right side of the assignment is a compile time constant, and can be determined to be in range of a short variable.

Henry
 
Henry Wong
author
Sheriff
Posts: 23260
124
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And this part, of course, compiles due to the compile time constant rule...

donald patrick wrote:
However,
short a = 10 * 3;  //DOES COMPILE???  Why? exactly.  Documentation says "literals are all interpreted as integers".  So, 10 and 3 are integers.  Yet, for "some" reason that line compiles?


Henry
 
Nikki Smith
Ranch Hand
Posts: 63
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was lurking a bit and read through this post out of curiosity. This is the first time I've heard of a compile time constant. I decided to Google it and found an old post you made on this topic like 7 years ago: https://coderanch.com/t/454384/java/compile-time-constant

Not sure if it's ok for me to add a question to this post or how that works. Apologies in advance if I'm doing this wrong, but even after reading that older post and checking Google, I'm also a bit confused. Why is it a necessary thing to declare final such as with OPs code in order for it to work as long as it's within range? I can understand getting an error if you tried to assign 3.141592 to an int but the range of a short is -32,768 to 32,767 and x = 10 or y = 3 are both within that range. Again, sorry if I doing something wrong by adding a question to this.
 
Stephan van Hulst
Saloon Keeper
Posts: 7476
134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When the variables are final, the compiler can reason that they will never change, and so it's safe to inline the values wherever the variable appears in the code. Arithmetic operations on constants can be performed at compile time to further improve the code. If the resulting value is within range, it can safely be assigned.

When a variable is not final, the values can not be inlined and it becomes much much more difficult for the compiler to reason that the result of the arithmetic operation is within range of the variable. The designers probably thought it was not worth it to add this logic to the compiler.
 
Henry Wong
author
Sheriff
Posts: 23260
124
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:When the variables are final, the compiler can reason that they will never change, and so it's safe to inline the values wherever the variable appears in the code. Arithmetic operations on constants can be performed at compile time to further improve the code. If the resulting value is within range, it can safely be assigned.


Interestingly, with Java 8, Java introduced the concept of "Effectively Final". I wonder if this has any effect to the compile time constant requirement?

[EDIT] Nope. The "effectively final" rule can't be used to replace the "final" declaration requirement for constant variables... so, with Java 8, it is still not a compile time constant without the "final" declaration.

Henry
 
Stephan van Hulst
Saloon Keeper
Posts: 7476
134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:Nope. The "effectively final" rule can't be used to replace the "final" declaration requirement for constant variables... so, with Java 8, it is still not a compile time constant without the "final" declaration.

Oh wow, that's a shame. I wonder what the reason for that is. I'm guessing it would take the compiler an extra pass to inline variables that are effectively final, but not final.
 
Campbell Ritchie
Marshal
Posts: 54886
155
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Effectively final (well, this is what I though) only applies to local variables or parameters used in anonymous classes or λs. It is possible to follow a local variable if it is only in scope for a few dozen lines. But what about fields? There may be hundreds of lines where they are used, and it would be too time‑consuming to verify whether they are ever reassigned.

At least I think that is what the situation is.
 
Stephan van Hulst
Saloon Keeper
Posts: 7476
134
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not really talking about fields though. Apparently the compiler can already determine whether local variables are effectively final, because they can be used in lambda expressions. If they can be used in lambda expressions, then why aren't they inlined, and why aren't operators optimized away?
 
Henry Wong
author
Sheriff
Posts: 23260
124
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
At least I think that is what the situation is.


When I tested it, it was with local variables. It worked with local variables that was declared final, but not those that are effectively final.

Henry
 
Campbell Ritchie
Marshal
Posts: 54886
155
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:. . . If they can be used in lambda expressions, then why aren't they inlined, and why aren't operators optimized away?
Maybe they will in Java11. You have a good point there.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!