• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Unreachable code

 
Fran Kindred
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How come this works? Should'nt this be unreachable?

 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, the JLS specifically prohibits compilers from complaining that this code is unreachable. The idea is that you might have a constant boolean field, such as

And later code like

By changing the value of DEBUG, you can control whether the println() is activated or not. But if the compiler were to complain that the println() is unreachable (since it knows DEBUG is false) then you'd be forced to remove this code, which would be annoying.

Nowadays code like this would probably be replaced with some sort of configurable logger. But at the time Java first came out, C/C++ were used to using preprocessor directives like

Java doesn't have preprocessor directives like C, but they left a few language features which emulate common C idioms, like this one.
 
Joe Borderi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is reachable; it just won't be executed.

As an example, suppose you have an abstract class that holds static final constants:

ClientGlobals.ENABLE_THIS_FEATURE is resolved at compile time, and the compiler in effect does a search and replace. Some clients may have this feature switched on and some switched off.
 
Fran Kindred
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
still a bit confused. my reasoning is I have set the actual value of false. I understand if I use a constant or even a variable and that is not set until runtime. Could you guys elaborate.

Many thanks!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As far as the compiler is concerned, there is very little difference between

and

(provided DEBUG is defined as a complie-time constant with value false). The people who wrote the JLS had already made a special case for how to treat a compile-time constant represented as a variable (DEBUG); they didn't consider it worth their while to make a separate, different case for how to treat a compile-time constant represented as a literal. Basically, the few times someone actually wants to write something like "if (false)", the compiler assumes they meant to write that, and it's not worthwhile making the compiler complain about it.

Ultimately, someone made this decision long ago, when the language was still being developed, and they put the decision into the language specification. It may not make perfect sense, but there's no compelling reason tochange it - it doesn't actually interfere with anyone's ability to write code.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want a general rule, javac only evaluates constant expressions, including literals, when necessary in order to generate the byte code. Examples are array dimensions and case expressions.

Otherwise, it's strictly don't ask don't tell.

Examples are your "if(false)...;" and "k=j/0;". Besides allowing conditional debug output code, another good reason is to let students generate exceptions without playing games.

On the other hand, javac takes type safety as far as it possibly can. A good example is the instanceof operator, where an expression with instanceof that could never be true (the lefthand operand's type could never refer to an object that is assignment compatible with the right operand) causes a compile error. "Integer i; if(i instanceof String);" fails to compile.

[ December 22, 2004: Message edited by: Mike Gershman ]
[ December 22, 2004: Message edited by: Mike Gershman ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic