• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

question on integer promotion / assignment

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have you tried this?:





(gotta rush, going home time).
 
Ranch Hand
Posts: 95
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Mark Neher
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 298
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Animesh:

Nice answer.
 
Mark Neher
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the answers. I was looking at the JLS yesterday, but had not yet found the relevant section.

MTN
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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."

 
Ranch Hand
Posts: 3852
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 .
 
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right, because "y" is a constant (by virtue of being defined "final").
Remove the "final" part, and you'll have a compile-time error.
 
reply
    Bookmark Topic Watch Topic
  • New Topic