Unreachable code compiler error [duplicate]
Asked Answered
S

7

25

The following code gives an unreachable statement compiler error

public static void main(String[] args) {
    return;
    System.out.println("unreachable");
}

Sometimes for testing purposes a want to prevent a method from being called, so a quick way to do it (instead of commenting it out everywhere it's used) is to return immediately from the method so that the method does nothing. What I then always do to get arround the compiler error is this

public static void main(String[] args) {
    if (true) {
        return;
    }
    System.out.println("unreachable");
}

I'm just curious, why is it a compiler error?? Will it break the Java bytecode somehow, is it to protect the programmer or is it something else?

Also (and this to me is more interesting), if compiling java to bytecode does any kind of optimization (or even if it doesn't) then why won't it detect the blatant unreachable code in the second example? What would the compiler pseudo code be for checking if a statement is unreachable?

Slocum answered 14/2, 2012 at 11:53 Comment(3)
you might want to read section 14.16 at this page: java.sun.com/docs/books/jls/second_edition/html/…Personification
Thanks for the link. I think I'm stuck in the "assembler" mindset because it's difficult for me to grasp how the "jumps" caused by the method call, the if statement and the return could let the unreachable line be detected in the first snippet but not in the second one.Slocum
Nice workaround with the if(true) thingie....Camm
I
23

Unreachable code is meaningless, so the compile-time error is helpful. The reason why it won’t be detected at the second example is, like you expect, for testing / debugging purposes. It’s explained in The Specification:

if (false) { x=3; }

does not result in a compile-time error. An optimizing compiler may realize that the statement x=3; will never be executed and may choose to omit the code for that statement from the generated class file, but the statement x=3; is not regarded as "unreachable" in the technical sense specified here.

The rationale for this differing treatment 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.

Reference: http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.21

Indoxyl answered 14/2, 2012 at 12:28 Comment(2)
Interesting to read (from your reference) that only the if statement is treated as a special case with regards to testing for unreachable code. And I can understand that an exception must be made for if(DEBUG) but why also for if(true)? I guess it was just easier that way. Thanks.Slocum
if (DEBUG) is the very same thing as if (true). DEBUG is a constant variable, because it is final and initialized with a compile-time constant expression. true is a literal of primitive type, thus also a constant expression. Even it was possible to differentiate between the two, such would only cause confusion. People would ask: Why if (DEBUG) but not if (true)?Urchin
S
8

Its because the compiler writer assumed that the human at the controls is dumb, and probably didn't mean to add code that would never be executed - so by throwing an error, it attempts to prevent you from inadvertently creating a code path that cannot be executed - instead forcing you to make a decision about it (even though, as you have proven, you still can work around it).

Spur answered 14/2, 2012 at 12:0 Comment(2)
+1: Its to protect you from doing something which is obviously wrong.Radu
But it might not be wrong if it's just a quick test.Crackerjack
E
2

This error is mainly there to prevent programmer errors (a swap of 2 lines or more). In the second snippet, you make it clear that you don't care about the system.out.println().

Euchre answered 14/2, 2012 at 11:59 Comment(2)
But could the second snippet not also be a mistake? For instance, if left in unintentionally.Slocum
Yes it could, but usually programmers do this to disable/enable some functionality and it is by far more obvious than putting a return before.Euchre
S
2

Will it break the Java bytecode somehow, is it to protect the programmer or is it something else?

This is not required as far as Java/JVM is concerned. The sole purpose of this compilation error is to avoid silly programmer mistakes. Consider the following JavaScript code:

function f() {
    return 
        {
            answer: 42
        }
}

This function returns undefined as the JavaScript engine adds semicolon at the end of the line and ignores dead-code (as it thinks). Java compiler is more clever and when it discoveres you are doing something clearly and obviously wrong, it won't let you do this. There is no way on earth you intended to have dead-code. This somehow fits into the Java premise of being a safe language.

Shivaree answered 14/2, 2012 at 12:0 Comment(2)
Why would the second snippet not cause an error then? I don't think it would be harder to detect (but I might be wrong).Slocum
Oh but it is detected. If you want proof, compile your code with the if(true), then decompile it using jad and you will see that the compiler removes the dead-codeEuchre
T
0

Example 1:

In this case you are return before any statement because of it compiler never going to execute that code.

public static void main(String[] args) {

    return;
    System.out.println("unreachable");
}

In second code I have put the statement above of return and its work now :)

Example 2:

    public static void main(String[] args) {

    System.out.println("unreachable"); // Put the statement before return
    return;
}

The reason behind this is that if you return sometime then code after it never going to execute because you already return the function data and as so it is shown unreachable code.

Turgot answered 16/9, 2014 at 11:4 Comment(0)
F
0

http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.21

says:

14.21. Unreachable Statements

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

Foss answered 18/3, 2015 at 16:6 Comment(0)
A
-2

It's because it's a waste of resources for it to even be there. Also, the compiler designers don't want to assume what they can strip out, but would rather force you to remove either the code that makes it unreachable or the unreachable code itself. They don't know what is supposed to be there. There's a difference between the optimizations where they tweak your code to be a bit more efficient when it's compiled down to machine code and blatantly just removing code "you didn't need."

Aluminize answered 14/2, 2012 at 11:57 Comment(1)
That does not explain why it's an error instead of a warning.Expellant

© 2022 - 2024 — McMap. All rights reserved.