How does the compiler in Java decide on unreachable code?

231 views Asked by At

How does a compiler decide on with unreachable code?

consider these

public class Test15 {

    public static final boolean verdict = false;
    public static final int verdictInt = 2;

    public static void main(String[] args) throws IOException {

        // case1
        if (verdict) {
            System.out.println(1);
        } else {
            System.out.println(2);
        }// compiles

        //case 2
        int val = 5;
        switch (val) {
         case verdictInt:System.out.println(3);
                        break;
        }// compiles

        //case 3
        while (false) {

        }// does not compile

        //case 4
        return 6;
        return 7;
        //does not compile

    }
}

So when the compiler decides that code is unreachable.Is it because of (for a lack of a better term) hard code(like case 4).Because as per my knowledge, verdict,verdictInt also qualify as compile time constants and according too. And as per my reading,being able to use the constant verdictInt as a switch case label indicates that it is a compile time constant.

Please let me know in case there are any basic flaws in my reasoning.

2

There are 2 answers

0
Makoto On BEST ANSWER

The Java Language Specification section on unreachable code is a good, but long read. I'll condense it into what translates for your question.

Case 1:

verdict could be seen as a flag variable; it may or may not be used for debug purposes. If it is, then breaking compilation would result in a major design goal miss. The specification explicitly calls this out:

The rationale for this differing treatment [with if as opposed to while] is to allow programmers to define "flag variables" such as:

static final boolean DEBUG = false;

and then write code such as:

if (DEBUG) { x=3; }

The idea is that it should be possible to change the value of DEBUG from false to true or from true to false and then compile the code correctly with no other changes to the program text.

Case 2:

Your switch statement can complete normally by the rules of the JLS:

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

  • The switch block is empty or contains only switch labels.
  • The last statement in the switch block can complete normally.
  • There is at least one switch label after the last switch block statement group.
  • The switch block does not contain a default label.
  • There is a reachable break statement that exits the switch statement.

Your switch doesn't have a default label, so your switch can complete normally. It just falls out of the switch.

Case 3:

This explicitly does not compile. Case 1 called some attention to it, but here it's spelled out, emphasis mine:

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 contained statement is reachable iff the while statement is reachable and the condition expression is not a constant expression whose value is false.

The condition expression is false, so you can't reach the contained statement, by definition.

Case 4:

return is a special case; it completes abruptly. Once a statement completes abruptly, any statements after that are not reachable by definition.

4
Begah On

In case 3, it knows it is not a loop because the value is always false. In case 4, it knows that there have been an infinite loop before, so it says unreachable code. But return 7; is unreachable also because there is return 6; before it that always run.

It is like doing :

printf("Hello");
return 0;
printf("Never reached code");

I don't know if this will give an unreachable error :

final int i = 5; float x = 0;
while(i<8) {
    x += 0.001f; 
    // Do Nothing
}
printf("Hello World");