Why doesn't the Java compiler generate an invalid statement error for an unreachable statement?

If I try to compile

for(;;) { } System.out.println("End"); 

Unreachable statement error message appears in Java compiler. But if I add another β€œunreachable” (for me) break statement and do this:

 for(;;) { if(false) break; } System.out.println("End"); 

It compiles. Why does this not lead to an error? Is Java an attempt to say that Two errors do make right?

+58
java if-statement unreachable-code unreachable-statement
Dec 24 '15 at 13:30
source share
5 answers

The behavior is defined in the JLS description of unreachable statements :

The then statement is available if an if-then statement is available.

So, the compiler determines that the then ( break; ) operator is available, regardless of the condition in the if .

And a little further, my hit:

The underlying for statement may complete normally if at least one of the following is true:

  • A for statement is available, a condition expression exists, and the condition expression is not a constant expression (Β§15.28) with a value of true.
  • There is a valid break statement that completes the for statement.

That way, for can fail normally, because then-statement contains a break . As you noticed, this will not work if you replace break with return .




The explanation is explained at the end of the section. Essentially, if has special processing that allows constructs such as:

 if(DEBUG) { ... } 

where DEBUG may be a compile-time constant.

+56
Dec 24 '15 at 13:38
source share
β€” -

As explained in my answer to a similar question , the concrete if(compile-time-false) constructor is freed from unreachable rules as an explicit backdoor. In this case, the compiler considers your break be reachable because of this.

+11
Dec 24 '15 at 13:40
source share

From JLS

The if-then operation may complete normally if at least one of the following is true:

The if-then statement is available and the condition expression is not a constant expression whose value is true.

> Then statement may end normally.

So if(false) .

This ability to "conditionally compile" has a significant impact, and is related to binary compatibility. If the set of classes that use such a flag variable is compiled and the conditional code is omitted, later it will not be enough to distribute only the new version of the class or interface that contains the flag definition. changing the flag value is therefore not compatible with binary with existing binaries. (There are other reasons for such incompatibilities, such as the use of constants in the case of labels in switch statements;)

+7
Dec 24 '15 at 13:40
source share

In principle, unreachable code is detected by analyzing the program statically without actually executing the code. While the condition will be checked at runtime. Thus, when this analysis takes place, it does not actually look at the state, but simply checks that break; available (available) via if .

+4
Dec 24 '15 at 16:23
source share

The main reason Java does not detect all unreachable statements is because it is generally impossible to answer whether the code is available or not. This follows from the fact that the stopping problem is unsolvable over Turing machines.

So, it is clear that all unattainable statements cannot be discovered, but why not try to evaluate the conditions? Imagine that the condition used is not just false , but something like ~x == x . For example, all of these operators will print true for each int x ( source ).

  System.out.println((x + x & 1) == 0); System.out.println((x + -x & 1) == 0); System.out.println((-x & 1) == (x & 1)); System.out.println(((-x ^ x) & 1) == 0); System.out.println((x * 0x80 & 0x56) == 0); System.out.println((x << 1 ^ 0x1765) != 0); 

Operations can be quite complicated; it takes time to solve them. This will significantly increase the build time, and in the end, it will not detect all unreachable statements. The compiler was designed to make some effort, but not spend too much time on it.

The only question remains: where to stop allowing conditions? The reasons for this have no mathematical justification and are based on use cases. The rationale for your specific case is given by JLS-14.21

+1
Dec 30 '15 at 9:21
source share



All Articles