Win a copy of Micro Frontends in Action this week in the Server-Side JavaScript and NodeJS forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

Implicit Narrowing

 
Ranch Hand
Posts: 261
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
case 1:
byte b=35;
char c=b;

case 2:
char c=(byte)b;

can anyone tell me why "case 1" results in compile time error whereas "case 2" won't.In both the cases iam doing the same thing.Please explain me the reason behind it and rules to be applied in these cases.
 
Abhishek Reddy
Ranch Hand
Posts: 261
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sorry if i misguided you its not the issue of switch case.I just used the word case 1 and case 2. please consider it as two different cases.

byte b=35;
char c=b;

the above line char c=b; is resulting in compile time error can you please explain me the reason for that...

But when i replaced the above two line with a single line
char c=(byte)35; the code compiled successfully. Iam unable to trace out the reason behind it.

Thanks in advance
 
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try to compile this:

Does this help?
 
Abhishek Reddy
Ranch Hand
Posts: 261
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok then what happens in this case

byte b=4;
byte b1=-b;

here the value -b fits in the range of byte then why is it raising error at compile time
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Abhishek,

There are two ways of casting a primitive data type into another. Case 2 as mentioned by you uses Explicit casting and is prone to data loss.

Implicit casting as in Case 1, gives compilation error as there is a possible loss of imformation.
char is 'unsigned' while byte is 'signed' and therefore am implicit conversion there might result in loss of information and hence discouraged.
[ August 22, 2006: Message edited by: Mannu ]
 
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


case 2 is an example of explicit narrowing operation. Its quite clear. It won't give any compilation error.

In case 1, surely you will get a compilation error as its not an implicit narrowing operation.

Implicit narrowing conversion will occur if b is a compile time constant and in the range of char and it only works for byte, char, short and int data types only.

e.g., following code is fine



More on it read read Implicit Conversions, Explicitly by Corey McGlone


Naseem
 
Ranch Hand
Posts: 2410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Abhishek Reddy Chepyala:
ok then what happens in this case

byte b=4;
byte b1=-b;

here the value -b fits in the range of byte then why is it raising error at compile time



The reason is that the unary - operator causes the byte to be promoted to int.

This is from the Java Language Specification 5.6.1

Some operators apply unary numeric promotion to a single operand, which must produce a value of a numeric type:

* If the operand is of compile-time type Byte, Short, Character, or Integer it is subjected to unboxing conversion. The result is then promoted to a value of type int by a widening conversion (�5.1.2) or an identity conversion.
* Otherwise, if the operand is of compile-time type Long, Float, or Double it is subjected to unboxing conversion.
* Otherwise, if the operand is of compile-time type byte, short, or char, unary numeric promotion promotes it to a value of type int by a widening conversion (�5.1.2).
* Otherwise, a unary numeric operand remains as is and is not converted.

In any case, value set conversion (�5.1.13) is then applied.

Unary numeric promotion is performed on expressions in the following situations:

* Each dimension expression in an array creation expression (�15.10)
* The index expression in an array access expression (�15.13)
* The operand of a unary plus operator + (�15.15.3)
* The operand of a unary minus operator - (�15.15.4)
* The operand of a bitwise complement operator ~ (�15.15.5)
* Each operand, separately, of a shift operator >>, >>>, or << (�15.19); therefore a long shift distance (right operand) does not promote the value being shifted (left operand) to long

 
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Stan James:
The compiler expects one block of code after a case, then another case or an end to the whole thing. Your two assignment statements count as two blocks. Wrap them with { curly braces } to make them one code block and see what happens.

And look into "break" to see why the output is still maybe not what you expect.




that's rubbish. not only is it out of context and not what the OP asked, but it's also incorrect. the code following each case label does not have to be enclosed in braces. Furthermore, if this WAS a switch statement, then it would be the second case, not the first, that caused the compiler error due to duplicate definition of variables.

The ACTUAL compiler error here is regarding narrowing, which is what the subject line of the thread said. pay attention.

- Adam
 
Adam Nace
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Abhishek Reddy Chepyala:
case 1:
byte b=35;
char c=b;

case 2:
char c=(byte)b;

can anyone tell me why "case 1" results in compile time error whereas "case 2" won't.In both the cases iam doing the same thing.Please explain me the reason behind it and rules to be applied in these cases.



The short answer to your question (which I didn't see very clearly stated in previous responses) has to do EXACTLY with your subject line, and with the compiler error. do you remember what it said? something about loss of presicion or loss of information?

The whole point is that narrowing can cause a large integer like 2^24 to be converted to 0 as a byte -> This is a whole different number! Because this sort of thing can happen, the compiler REQUIRES that you always EXPLICITLY state your intent to narrow a value. This was a design consideration when the language was designed. It wasn't absolutely necessary, but it sure saves a lot of time debugging errors caused because programmers forgot that there was narrowing going on.

so there's your answer. this is a safety net, and it isn't unique in that aspect of the compiler. There are other compile time errors which serve the same sort of purpose.

- Adam
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yup, Adam, I fumbled that one badly. Didn't trust the topic because I mangled the syntax with another language I was using at the time. At least it was here at "the friendly place" where friends like the OP graciously corrected me and went on.
[ August 24, 2006: Message edited by: Stan James ]
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic