• Post Reply Bookmark Topic Watch Topic
  • New Topic

Compiler inconsistencies?  RSS feed

 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This thread got me to wondering (dangerous I know ) but why does this:

result in a compile time error of unreachable statement and this:

does not?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The compiler seems to be correctly following the JLS rules for unreachable statements (JLS 14.20). The expression "false" is regarded as a constant expression (meaning, a compile-time constant expression as defined in JLS 15.28) while "i != i" is not. Basically, the compiler is not allowed to use common sense in this case.
[ May 06, 2003: Message edited by: Jim Yingst ]
 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yea. It would also brings up some intersting implemention issues as well for example:

compiles to this assembly:

whereas this:

compiles to this assembly:

If the literal false were allowed how would you implement it? Like this:

That is an obvious statement unreachable, whereas the the i != i is not.
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The expression "false" is regarded as a constant expression (meaning, a compile-time constant expression as defined in JLS 15.28) while "i != i" is not. Basically, the compiler is not allowed to use common sense in this case.
Why is it then that this code compiles:

... and this one doesn't:
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Eugene Kononov:
The expression "false" is regarded as a constant expression (meaning, a compile-time constant expression as defined in JLS 15.28) while "i != i" is not. Basically, the compiler is not allowed to use common sense in this case.
Why is it then that this code compiles:


This is done to simulate "conditional compiling":

That if statement will produce *no* bytecode if DEBUG is a final static field set to false.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
BTW, in a multithreaded environment, i != i doesn't need to be always false!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
True - especially (perhaps only) if i is declared volatile.
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is done to simulate "conditional compiling"
I looked at the JLS again, and yes, that is the justification. Very subtle and contradictory, unless you really read the JLS closely.
 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I looked at the JLS again, and yes, that is the justification. Very subtle and contradictory, unless you really read the JLS closely.

From that reasoning though, it would seem that it should also be allowed in the case of a for loop because of the possible side-effects of the first statement. It is allowed in a do loop :
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very subtle and contradictory, unless you really read the JLS closely.
Such is the nature of the JLS. It's actually very self-consistent (in the rules themselves, if not in the motivations behind some of the rules), but it rarely seems that way while you're studying it.
From that reasoning though, it would seem that it should also be allowed in the case of a for loop because of the possible side-effects of the first statement.
Well, the general principle they're trying to follow is to disallow constructs in which at least some part of the code is clearly useless - not to allow any code which has at least some side effects. Sure the first part of the for loop might have side effects - but if the condition is a constant false, there's no conceivable use for having a for loop there in the first place. The programmer should have just made the first part a plain statement, outside any loop construct. The fact that he didn't probably indicates a misunderstanding of how his code would work.
On the other hand, if (false) does have a possible use (however strange it may seem), due to the prevalence of the conditional compilation idiom among the C programmers Java designers were trying to attract. Note that "if (false)" is kinda silly, but "if (DEBUG)" makes a bit more sense - you can make DEBUG public static final (so it's a compile-time constant), and set it to true or false just before compiling - allowing a single point of control for any number of other statements.
It is allowed in a do loop :
Yeah, this is kind of weird. It would make sense to me if they disallowed this, since there's no sensible reason I can imagine for a constant false while condition here. But if they did disallow it, they would've had to call it something other than an "unreachable statement" - all statements in this code are reachable. Maybe throw a SillyAndPointlessCodeError?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!