If(False) VS. While(False): Unreachable Code VS. Dead Code

if(false) vs. while(false): unreachable code vs. dead code

The JLS section on unreachable code explains the rationale. Essentially, Java normally shouldn't use conditional compilation like C routinely does with #ifdef, but there are some situations (such as debugging, and in particular backward binary compatibility) where allowing the compiler to entirely strip out code is needed, and so the specific construct if(false) is permitted for that purpose.

Why is an if/else if/else for a simple boolean not giving an unreachable code error

From JLS 14.21. Unreachable Statements

It is a compile-time error if a statement cannot be executed because it is unreachable.

and

The else-statement is reachable iff the if-then-else statement is reachable.

Your if-then-else statement is reachable. So, by the definition the compiler thinks that the else-statement is reachable.

Note: Interestingly the following code also compiles

// This is ok
if (false) { /* do something */ }

This is not true for while

// This will not compile
while (false) { /* do something */ }

because the reachability definition for while is different (emphasis mine):

The contained statement is reachable iff the while statement is reachable and the condition expression is not a constant expression whose value is false.

Unreachable statement: while true vs if true

There are quite strict rules when statements are reachable in java. These rules are design to be easily evaluated and not to be 100% acurate. It should prevent basic programming errors. To reason about reachability in java you are restricted to these rules, "common logic" does not apply.

So here are the rules from the Java Language Specification 14.21. Unreachable Statements

An if-then statement can complete normally iff it is reachable.

So without an else, statements after an if-then are always reachable

A while statement can complete normally iff at least one of the following is true:

  • The while statement is reachable and the condition expression is not a constant expression (§15.28) with value true.

  • There is a reachable break statement that exits the while statement.

The condition is a constant expression "true", there is no break. Hence it does not complete normally.

Why Java identifies unreachable code only in case of while loop?

As described in Java Language Specification, this feature is reserved for "conditional compilation".

An example, described in the JLS, is that you may have a constant

static final boolean DEBUG = false;

and the code that uses this constant

if (DEBUG) { x=3; }

The idea is to provide a possibility to change DEBUG from true to false easily without making any other changes to the code, which would not be possible if the above code gave a compilation error.

Why isn't unreachable code detected when an if condition is a constant?

From the Java Language Specification, 14.21. Unreachable Statements (emphasis by me):

It is a compile-time error if a statement cannot be executed because
it is unreachable.

This section is devoted to a precise explanation of the word
"reachable." The idea is that there must be some possible execution
path from the beginning of the constructor, method, instance
initializer, or static initializer that contains the statement to the
statement itself. 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 while the code is indeed unreachable, the compiler explicitly does not regard it as such. The reason stated is to allow programmers to define "flag" variables such as

static final boolean DEBUG = false;

if (DEBUG) { x=3; }

It should be possible to switch DEBUG between false and true without having to change anything else in the code (due to compilation errors).

Unreachable code error vs. dead code warning in Java under Eclipse?

The first does not compile (you got an error), the second compiles (you just got a warning). That's the difference.

As to why Eclipse detects dead code, well, that's just the convenience of an integrated development tool with a built-in compiler which can be finetuned more as opposed to JDK to detect this kind of code.

Update: the JDK actually eliminates dead code.

public class Test {
public void foo() {
System.out.println("foo");
if(true)return;
System.out.println("foo");
}
public void bar() {
System.out.println("bar");
if(false)return;
System.out.println("bar");
}
}

javap -c says:


public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

public void foo();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String foo
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/StrV
8: return

public void bar();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #5; //String bar
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #5; //String bar
13: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return

}

As to why it (Sun) doesn't give a warning about that, I have no idea :) At least the JDK compiler has actually DCE (Dead Code Elimination) builtin.

if(false) vs. while(false): unreachable code vs. dead code

The JLS section on unreachable code explains the rationale. Essentially, Java normally shouldn't use conditional compilation like C routinely does with #ifdef, but there are some situations (such as debugging, and in particular backward binary compatibility) where allowing the compiler to entirely strip out code is needed, and so the specific construct if(false) is permitted for that purpose.

Obvious false condition in else if, not giving dead code for body inside

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.



Related Topics



Leave a reply



Submit