| Author |
question on integer promotion / assignment
|
Mark Neher
Greenhorn
Joined: Apr 28, 2004
Posts: 9
|
|
On one of Dan Chisholm's exams, there was the following line buried in a question: char primitiveChar = 'b'-'a'; The answer indicated that this was OK. I expected a compiler failure on this line -- I thought that the literal chars would be promoted to ints, and the assignment would be flagged for not casting it back down to a char. Indeed, the K&B book outlines a similar scenario for compiler error using bytes: byte b = 3, c = 8; byte d = b + c; Trying to actually compile these does allow the char case, and gives an error on the (seemingly same to me) byte case. Can anyone explain the difference ?? Thanks, Mark
|
 |
Barry Gaunt
Ranch Hand
Joined: Aug 03, 2002
Posts: 7729
|
|
Have you tried this?: (gotta rush, going home time).
|
Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
|
 |
shandilya popuru
Ranch Hand
Joined: Dec 21, 2004
Posts: 95
|
|
hi mark char is just an unsigned int as long as the value is between 0 to 65536 u dont get an error try this u get an error char c; c='a'-'b'; cos the value`d be -1 out of the range of char but this c='b'-'a'; this`ll return 1 that`d easily fit into chars range hope that xplains ur doubt
|
sandy
|
 |
Mark Neher
Greenhorn
Joined: Apr 28, 2004
Posts: 9
|
|
OK, so char a = 'a'; char b = 'b'; char c = b - a; from Barry, gives a compiler error, as did byte b = 3, c = 8; byte d = b + c; from K & B. Further, changing K & B to byte e = 3 + 8; works, as did the original Dan Chisholm question of char primitiveChar = 'b'-'a'; The pattern is clear; it still isn't obvious to me why the byte and char literals in the working examples aren't promoted to ints before the arithmetic. From K & B: "We know that a literal integer is always an int, but more importantly -- the result of an expression involving anything int-sized or smaller is always an int. In other words, add two bytes together and you'll get an int -- even if those two bytes are tiny." The two working examples would seem to fit this qualification: the result of an expression involving anything int-sized or smaller is always an int.
|
 |
Javier Diaz
Greenhorn
Joined: Mar 17, 2003
Posts: 16
|
|
I *think* it is because when you use an arith expresssion that involves just constants the compiler can optimize your arithmetic so the code in the .class has not got the arith, but just the result (use javap -c <ClassName> ) So the promotion rules do not apply as there is really no operation involved ... Test 1 char one = 'b' - 'a'; 0: iconst_1 // int 1 1: istore_1 2: return Test 2 char one = 'c' - 'a'; 0: iconst_2 //int 2 1: istore_1 2: return Test 3 (out of range, COMPILE ERROR) The compiler checks if the result would be out of range char one = 'a' - 'b'; Tests.java:10: possible loss of precision found : int required: char char one = 'a' - 'b'; Test 4 (loop around, force) char one = (char) ('a' - 'b'); 0: ldc #2; //int 65535 2: istore_1 3: return Hope this helps -Javier [ January 18, 2005: Message edited by: Javier Diaz ]
|
 |
Animesh Shrivastava
Ranch Hand
Joined: Jul 19, 2004
Posts: 298
|
|
There is an implicit narrowing conversion from a byte, short, char, or int to a byte, short, or char when the source is a constant expression that can be evaluated at compile time and the value fits in the target. This does not apply to arguments in method invocations. In the question given by you, 'a' and 'b' are literals which are constants, So, it compiles fine, Now as said by Barry, this would give a compiler error char a = 'a'; char b = 'b'; char c = b - a; Because here a, b are not constants Going through the explanation above the below would not give any compiler error, final char a = 'a'; final char b = 'b'; char c = b - a; For more info on this, See JLS 5.2 Assignment Conversion.
|
 |
Mike Gershman
Ranch Hand
Joined: Mar 13, 2004
Posts: 1272
|
|
Animesh: Nice answer.
|
Mike Gershman
SCJP 1.4, SCWCD in process
|
 |
Mark Neher
Greenhorn
Joined: Apr 28, 2004
Posts: 9
|
|
Thanks for the answers. I was looking at the JLS yesterday, but had not yet found the relevant section. MTN
|
 |
Barry Gaunt
Ranch Hand
Joined: Aug 03, 2002
Posts: 7729
|
|
Now I come back and everything is done Here's another interesting junk of JLS:
15.28 Constant Expression ConstantExpression: Expression A compile-time constant expression is an expression denoting a value of primitive type or a String that is composed using only the following: * Literals of primitive type and literals of type String * Casts to primitive types and casts to type String * The unary operators +, -, ~, and ! (but not ++ or --) * The multiplicative operators *, /, and % * The additive operators + and - * The shift operators <<, >>, and >>> * The relational operators <, <=, >, and >= (but not instanceof) * The equality operators == and != * The bitwise and logical operators &, ^, and | * The conditional-and operator && and the conditional-or operator || * The ternary conditional operator ? : * Simple names that refer to final variables whose initializers are constant expressions * Qualified names of the form TypeName . Identifier that refer to final variables whose initializers are constant expressions Compile-time constant expressions are used in case labels in switch statements (�14.10) and have a special significance for assignment conversion (�5.2). A compile-time constant expression is always treated as FP-strict (�15.4), even if it occurs in a context where a non-constant expression would not be considered to be FP-strict. Examples of constant expressions: true (short)(1*2*3*4*5*6) Integer.MAX_VALUE / 2 2.0 * Math.PI "The integer " + Long.MAX_VALUE + " is mighty big."
|
 |
ankur rathi
Ranch Hand
Joined: Oct 11, 2004
Posts: 3829
|
|
Mark , may be my explanation you will not like but simple one : if you are assigning a variable into a variable ( x = y ) then you have to make sure to compiler that you will not go to the out of range of left hand side variable ( x ) . Like this will give no error at compile time .
|
 |
Andris Jekabsons
Ranch Hand
Joined: Jan 20, 2004
Posts: 82
|
|
Right, because "y" is a constant (by virtue of being defined "final"). Remove the "final" part, and you'll have a compile-time error.
|
 |
 |
|
|
subject: question on integer promotion / assignment
|
|
|