4

Going through some old code written by one of my teammate, I found this really strange code:

if (...) {
    // some code

} else if (this == null) {
    System.out.println("I expected this to be dead code!");
}

Strange isn't it. AFAIK, this == null condition can never be true, which should be obvious to the compiler, as it knows the meaning of this and null both. But to my surprise, that wasn't marked as dead code.

I tried this code both in Eclipse, and through command line. I ran the following command to enable all warning:

javac -Xlint:all MyClass.java

Still it didn't gave any warning.

On contrary, if I change the else if block to:

else if (false) {
    System.out.println("As expected, this is dead code");
}

The statement inside was marked as dead code, as I expected.

So why this behaviour? This only leads me to think that there might be some condition where this can actually be null. Is it?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Are you sure the compiler is actually all-inclusive in this check? For the sake of knowing, what is the context of `this==null`? Instance method? Inner class, perhaps? – nanofarad Oct 08 '13 at 10:29
  • @hexafraction What do you mean? – Rohit Jain Oct 08 '13 at 10:29
  • 1
    The compiler may not treat every piece of dead code obvious to human eyes(and even implied in the JLS) as dead code. – nanofarad Oct 08 '13 at 10:30
  • @hexafraction What could be the possible reason. I know compiler may not be smart enough to detect all the warning. But the situation as obvious as this should be detectable. – Rohit Jain Oct 08 '13 at 10:32
  • 1
    Or maybe the compiler does not check this condition. – Freedom Oct 08 '13 at 10:33
  • @RohitJain Imagine you are developing the compiler. You would develop this check by (exhaustively) listing all implicitly-always-foo conditions. This is one that may not immediately stand out unless you were to see an example of someone that *did* realize it, using it. – nanofarad Oct 08 '13 at 10:35
  • @hexafraction Hmm. That quite makes sense. – Rohit Jain Oct 08 '13 at 10:38
  • @hexafraction: The Java standard requires that implementations recognize certain forms of always-true and always-false expressions, and that they *behave as though* they evaluate all others at run-time. Whether an implementation behaves as though it recognizes an always-true or always-false expression does not depend upon the cleverness of the implementation, but merely on the form of the expression itself. – supercat May 13 '17 at 16:57

3 Answers3

6

The JLS has a definition of unreachable code:

The analysis takes into account the structure of statements. Except for the special treatment of while, do, and for statements whose condition expression has the constant value true, the values of expressions are not taken into account in the flow analysis.

So this is not considered "unreachable".

Also see this discussion about unreachable code errors and dead code warnings.

Community
  • 1
  • 1
Thilo
  • 257,207
  • 101
  • 511
  • 656
0

The compiler seems to be spotty in detecting implicitly-always-false conditions, and even if it is implied or stated by the JLS/is obviously false, then it may not pick up on that fact. The is-null check isn't as straightforward to catch when simply listing a set of "obvious conditions" to check, so it may have been overlooked.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
0

Rice's theorem implies that checking whether a Java expression evaluates to false is undecidable. i.e. it is theoretically impossible to determine whether some arbitrary code is dead.

Since the java compiler cannot detect all dead code, the developers settled on a very specific set of instances of dead code that they could detect.

Konstantin Weitz
  • 6,180
  • 8
  • 26
  • 43