Why does compiler build return unreachable code in some cases
Asked Answered
M

4

8

If I write

private void check(){
   if(true)
      return;

   String a = "test";
}

Above code works normally, but if I write

private void check(){
   return;

   String a = "test";
}

The compiler/gradle in Android studio doesn't let this one through even though it's the same, and it says that the code after return in example 2 is unreachable.

I don't have any issues regarding this but I am eager to know why?

Martita answered 16/2, 2018 at 10:30 Comment(3)
maybe it has something to do with decidability?Cher
In the second example the compiler can decide that the assignment will never be reached without thinking about semantics. In the first example the compiler has to understand the if(true) in order to deduct the assignment isn't reachable. This simple case can be implemented, but it doesn't make much sense since the general case is probably equivalent to the halting problem. A cut had to be made somewhere. Doing this at the syntax level gives most benefit for little workComanchean
In fact, there are cases where NOT getting an unreachable code error is desired. For example: if (DEBUG) { someDebugCode(); }, where DEBUG is a constant defined as either true or false. If it is false the whole if body is unreachable but you don't want to be forced to remove it.Teratoid
I
1

This is explained by the Unreachable Statements part of the Java Language Specification.

There are quite a few rules, with an interesting special case. This is a compile time error :

while (false) {
    // this code is unreachable
    String something = "";
}

while this is not :

if (false) {
    // this code is considered as reachable
    String something = "";
}

The given reason is to allow some kind of conditional compilation, like :

static final boolean DEBUG = false;
...
if (DEBUG) { x=3; }

So in your case :

private void check(){
    if(true)
        return;

    // NO compilation error
    // this is conditional code
    // and may be omitted by the compiler
    String a = "test";
}

is not an error because of the special if treatment, using while instead is not accepted :

private void check(){
    while(true)
        return;

    // "Unreachable statement" compilation error
    String a = "test";
}

This is also en error :

private void check(){
    if(true)
        return;
    else
        return;

    // "Unreachable statement" compilation error
    String a = "test";
}
Interjection answered 16/2, 2018 at 15:33 Comment(0)
R
2

javac compiler does very little optimizations, so it simply does not "see" that if(true) is always true(but you should get a warning); but C1/C2 JIT compilers will - so that code will simply be a return, without an if statement.

Rosemare answered 16/2, 2018 at 15:9 Comment(0)
I
1

This is explained by the Unreachable Statements part of the Java Language Specification.

There are quite a few rules, with an interesting special case. This is a compile time error :

while (false) {
    // this code is unreachable
    String something = "";
}

while this is not :

if (false) {
    // this code is considered as reachable
    String something = "";
}

The given reason is to allow some kind of conditional compilation, like :

static final boolean DEBUG = false;
...
if (DEBUG) { x=3; }

So in your case :

private void check(){
    if(true)
        return;

    // NO compilation error
    // this is conditional code
    // and may be omitted by the compiler
    String a = "test";
}

is not an error because of the special if treatment, using while instead is not accepted :

private void check(){
    while(true)
        return;

    // "Unreachable statement" compilation error
    String a = "test";
}

This is also en error :

private void check(){
    if(true)
        return;
    else
        return;

    // "Unreachable statement" compilation error
    String a = "test";
}
Interjection answered 16/2, 2018 at 15:33 Comment(0)
P
0

When it tries to compile it builds an abstract syntax tree. In the first case 'true' is an anonymous variable, so two branches will be added, even only one of them is possible. In the 2nd case, there is only one possible branch to create, which will never reach its end.

Pitiable answered 16/2, 2018 at 10:38 Comment(0)
E
0

The difference is these require two different analyses to determine the behavior. The first example requires semantic analysis while the later requires syntactical analysis. Compilers are experts in syntax; this is what they are built to do. They often struggle with semantics, though. Performing static semantic analysis takes more effort from the compiler writers and can be extremely difficult to get correct in general.

Eula answered 16/2, 2018 at 15:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.