what does Dead Code mean under Eclipse IDE Problems Section - java

I am using Eclipse Helios IDE for our Web Application development.
Under Problems section in Eclipse, for some of lines the description is displayed as "Dead Code".
Could anybody please tell me what does Dead Code actually mean ?
Please see the screen shot for your reference.
For example this part is shown as dead code under Eclipse
else {
int length;
if (ar != null)
length = Array.getLength(ar);
else
length = 0; // This line is dead code

In Eclipse, "dead code" is code that will never be executed. Usually it's in a conditional branch that logically will never be entered.
A trivial example would be the following:
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
It's not an error, because it's still valid java, but it's a useful warning, especially if the logical conditions are complex, and where it may not be intuitively obvious that the code will never be executed.
In your specific example, Eclipse has calculated that ar will always be non-null, and so the else length = 0 branch will never be executed.
And yes, it's possible that Eclipse is wrong, but it's much more likely that it's not.

Dead code is code that will never be executed, e.g.
boolean b = true
if (!b) {
....
// dead code here
}

Dead code means, that there is no way that this code will be executed.
Sometimes you even can't compile it (like this case:)
private Boolean dead_code()
{
return true;
//Dead code below:
dosomething();
}
But in other cases this is not too obvious, eg this statement:
b=true;
[...]
if (b==false)
{
//Dead code
}
If you have this message, there is some major flaw in your code. You have to find it, otherwise your app won't work as intended.

There are two kinds of diagnostics that Eclipse gives out for marking code that will/may not be executed at runtime.
1) Unreachable code: These are the usual java warnings that follow the unreachability rules of the JLS, and are also given by javac. These are meant to be compile errors. Examples:
int foo() {
return 1;
int i = 1; // Unreachable
}
int foo2() {
while (true);
int i =1; //Unreachable
}
There are other more complicated examples :)
2) Dead code: This is Eclipse's own static analysis warnings, and are mostly tied out of the null analysis i.e.
void foo() {
Object o = null;
if (o == null) {
} else {
// dead code
}
The examples given above should NOT give a dead code warning. i.e.
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
should not give the warning, because JLS forbids the compiler to evaluate the 'value' of variables. All that we can evaluate is the 'nullness'
Hope this helps

You might be having an Null pointer exception in the lines above the "Dead Code" lines.
Make sure you check for "Null Pointer" exception.

It is possible that you have used the variable ar before. Then the compiler knows that the line in the else statement will never be executed. Either there will be a NullPointerException at the place where you used ar or the first part of the if statement will be executed.

let me give some answer for the dead code.
Eg:
public class UnreachableTest{
public static void main(){
try{
// some code
}
catch(Exception exc){
throw new NullPointerException();
System.out.println("Unreachable line"); // compile time error
}
}
}
here the System.out.println("Unreachable line"); is never executed.
Which in turn considered to be a dead code.
Another example may be:
int func(int i, int j)
{
int sum = i + j;
return i + j; // never actually using the sum
}
simple the function returns i + j; never really uses sum.
Sum is considered to be dead code here.

Some other case when this happens.
System.out.println("result :" + result + ":" + result.isEmpty());
if (result == null)
return result;
else if(!result.isEmpty())
str.append(result + " ");
1) Here as you you are printing result and checking isEmpty() eclipse assumes that result is not null so it will not go in if. So return result is dead code.
2)Now let say result is coming null so you will get NullPointerException in result.isEmpty() so again it will not go in if and return result is deadcode
To make this work just comment out System.out.println().

Eclipse gives this warning if the condition check you are giving may never be satisfied. Following are some examples
Object o=null;
if(o!=null) {
//Some code
}
Here Dead code warning will come as Object is already made null
Another example is given below
BSTTest bstTest=null;
bstTest.test=10;
if(bstTest==null) {
//some code
}
Here the code is trying to access a variable of the class. As the variable is already accessed, eclipse will give dead code warning in if(bstTest==null) as bstTest may not be null when the variable is already accessed.
Note: Here bstTest.test will give null pointer exception

Simple Example of Dead Code
public class IfTest {
public static void main(String[] args) {
if (true) {
if(false) {
System.out.println("a"); //Dead code, Never be Execute this if block.
}else {
System.out.println("b");
}
}
}

To simplify the term's Unreachable code and dead code:
Unreachable Code is a code block/statement in Java to which the control never reaches and never gets executed during the lifetime of the program. Following is the example of unreachable code. This generates compiler time error.
public void unreachableCodeExample() {
System.out.println("This will execute");
return;
System.out.println("This will not"); //This is Unreachable code
}
While A Dead code is an unreachable code, but it doesn’t generate compile time error. But if you execute it in eclipse (Or some other IDE) it gives you a warning. See below example,
public void deadCodeExample() {
if (true) {
System.out.println("This will execute");
return;
}
System.out.println("This will not"); //This is dead code
}

Dead code is the section of our code that is never going to execute runtime, its useless
EX:
if(false){ // statements }
For more example u can refer : DeadCode Examples

Try this:
while (true) {
if(false == true) break;
}
S.O.P("I will never reach here!") <-- This code will never be executed.
The code is valid as it conform to the compiler, however in reality the loop will never exit, and in effect S.O.P will never be executed.

Related

Why does compiler build return unreachable code in some cases

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?
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.
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";
}
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.
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.

Android Studio reports "Unreachable Code" with enum comparison

I'm doing something that should be trivial- retrieving an enum value from a property and comparing it with a constant of that enum in an if statement. However Android Studio claims the true case is unreachable code and won't compile.
The block is:
if (ScanState.getScanMode() != ScanState.ScanModeEnum.SCAN_IDLE)
{
//We're already scanning, but user wants to stop.
stopScanning();
}
else
{
ScanState.setScanMode(newMode);
restartScan();
buttonFlashMode = btnMode;
buttonFlasher();
}
where in an extra ScanState class, I have:
public static ScanModeEnum getScanMode() {
return scanMode;
}
public static void setScanMode(ScanModeEnum scanMode) {
ScanState.scanMode = scanMode;
}
public enum ScanModeEnum
{
SCAN_IDLE,
SCAN_PERSON,
SCAN_BIKE,
SCAN_SEARCH
}
private static ScanModeEnum scanMode = ScanModeEnum.SCAN_IDLE;
Variants I've tried, which Android Studio claims will all evaluate to false are
if(ScanState.getScanMode() == ScanState.ScanModeEnum.SCAN_IDLE)
if(ScanState.getScanMode().compareTo(ScanState.ScanModeEnum.SCAN_IDLE)!=0)
if(ScanState.ScanModeEnum.SCAN_IDLE == ScanState.ScanModeEnum.SCAN_IDLE)
if(ScanState.ScanModeEnum.SCAN_IDLE.equals(ScanState.ScanModeEnum.SCAN_IDLE))
I'm new to Java (more familiar with C#), but an answer to this question suggests that my understanding of this is sound. Is there some stupid mistake I'm making?
Have you tried debugging this and verifying that the block is never actually reached?
I agree this is a very strange situation. If it persists, I can recommend swapping the enum for int constants, and conducting the check on them. It's not a real fix, but more of a workaround, but at least it can unblock you for the moment.
Good grief. After making a seperate method as suggested and discovering the problem lay elsewhere I had a look further up the code. The complete method was;
public void onScanButtonPress(#ButtonFlashMode int button)
{
ScanState.ScanModeEnum newMode;
#ButtonFlashMode int btnMode = 0;
switch (button)
{
case FLASH_BIKE:
newMode = ScanState.ScanModeEnum.SCAN_BIKE;
btnMode = FLASH_BIKE;
case FLASH_PERSON:
newMode = ScanState.ScanModeEnum.SCAN_PERSON;
btnMode = FLASH_PERSON;
default:
//Unhandled.
return;
}
if (ScanState.getScanMode() != ScanState.ScanModeEnum.SCAN_IDLE)
{
//We're already scanning, but user wants to stop.
stopScanning();
}
else
{
ScanState.setScanMode(newMode);
restartScan();
buttonFlashMode = btnMode;
buttonFlasher();
}
}
Since I've forgotten to put break statements in the cases of the switch, it'll always return before the if is ever evaluated. It'll therefore never evaluate to true and so the error is correct- if misleading since it implies (to me at least!) that the if statement does get evaluated. Thanks for the comments, and I figured this was worth leaving (despite being indeed a stupid mistake) because others might be caught out by this.
EDIT: As mentioned by #Bubletan and #MarkoTopolnik, this would not result in a compiler error. Leaving the response as documentation of something that would NOT cause this error.
Do you call anywhere in your code setScanMode? (outside that else block). The compiler may be detecting that the static variable scanMode is never modified, and therefore ScanState.getScanMode() is always ScanState.ScanModeEnum.SCAN_IDLE, thus code not reachable.
Try invoking setScanMode somewhere in your code (with a value different than ScanState.ScanModeEnum.SCAN_IDLE) and see if this error disappears.

Why does a String need to be initialized even if the assignment will happen later?

I get the "The local variable string may not have been initialized" error with the following code. The code itself doesn't make sense it was written just for the sake of exercise.
public class StringExercise
{
public static void main(String[] args)
{
String string; // initializing here fixes the issue
for (int i = 0; i < 10; ++i)
{
if( (i % 4) == 2 )
{
string = "Number: " + i;
}
}
System.out.println(string); // this is marked as wrong by Eclipse
}
}
To get it working it is sufficient to initialize String as expressed in the comment above.
My question is why is it needed? The method println will never be given null and initialization will happen the first time the condition in the loop returns true. Am I doing something wrong or is it just Java being overcautious over programmer's errors? If the latter, how is it justified from the theoretical point of view?
My question is why is it needed?
Because even though your code is "logically" written so that string will indeed be initialized in the loop, the compiler doesn't know it. All it sees is:
for (loop; elements; here)
if (someCondition)
string = something;
In short: a compiler will not check the logic of your code; it it only smart enough as to check for syntax errors, but after that, the bytecode generation itself is "dumb".
And as Java requires that all variables be initialized before use, you get this compiler error.
The compiler can't guarantee that string = "Number: " + i; will be executed within your for and if.

Why doesn't this if-statement short circuit?

I'm currently fixing a bug in someone else's Java code, but I cannot explain the bug. The code in question is the following if-statement:
if (locked && DEBUG_ENABLED
&& owner != null
&& (owner.equals(playerName) || subowner.equals(playerName))
&& handleCommand(playerName, message)) {
....
} else {
....
}
In which DEBUG_ENABLED is initialized as private static boolean DEBUG_ENABLED = false; and handleCommand functions like this:
public boolean handleCommand(String name, String msg) {
if(msg.equals("Command1")) {
....
} else if(msg.equals("Command2")) {
....
} ....
} else { // No matching command
return false;
}
return true;
}
What puzzles me is that even though DEBUG_ENABLED is set to false, the code still calls and executes the handleCommand function. I always thought this wasn't supposed to happen due to short circuiting.
The if-statement itself in total is still evaluated as false, since only the code inside the else-block in the first snippet is executed.
So, how come this if-statement is behaving like this? Is it failing to short-circuit, or do I misunderstand the principle, or is there something completely different wrong with this part of code? (Besides the missing null check for subowner that is, which is done outside of this part.)
It is not possible that the && operator fails to short-circuit. Were you using & perhaps? If not it means you have made some false assumptions that previous conditions before the last one were false.

Why is an error issued with an if statement in Java even though it is always true? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Compiler complains about “missing return statement” even though it is impossible to reach condition where return statement would be missing
The following method in Java compiles fine.
public String temp() {
while(true) {
if(true) {
// Do something.
}
}
}
The method has an explicit return type which is java.lang.String with no return statement though it compiles fine. The following method however fails to compile.
public String tempNew() {
if(true) {
return "someString";
}
}
A compile-time error is issued indicating "missing return statement" even though the condition specified with the if statement is always true (it has a boolean constant that is never going to be changed neither by reflection). The method must be modified something like the following for its successful compilation.
public String tempNew() {
if(true) {
return "someString";
} else {
return "someString";
}
}
or
public String tempNew() {
if(true) {
return "someString";
}
return "someString";
}
Regarding the first case with the while loop, the second case appears to be legal though it fails to compile.
Is there a reason in the second case beyond one of the compiler's features.
Because it is dead code. The dead code analysis is done in a separate pass to the method return analysis, which does some more in-depth analysis that looks inside branch conditions.
From the java tutorial:
You can implement an infinite loop using the while statement as follows:
while (true){
// your code goes here
}
so the compiler knows this is infinite, and therefore may not return - ie not necessarily needing a return statement.
The if (true) line (on it's own), on the other hand will return and therefore needs to cover all returning branches.

Categories

Resources