Say I have something like this in a C Code. I know you can use a #define
instead, to make the compiler not compile it, but just out of curiosity I\'m asking if
in Java, the code inside the if won't even be part of the compiled code. It must compile, but it won't be written to the compiled bytecode. It actually depends on the compiler, but I don't know of a compiler that doesn't optimize it. the rules are defined in the JLS:
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.
Don't know about C.
I can recall scenarios in my Java and C# programs, where it did (optimize it out). But I also know it depends very much on the compiler settings - therefore the scenario is too unspecific.
In a Java scenario we had the const values in one Java source file, while they were used in another class (file). What happened was, when we just changed and recompiled the file with the const values, nothing changed in the flow of the using parts. We had to recompile the whole project (which is the proof it was optimized out).
Below is specific to C language. I don't know how Java handles it.
Since int
is defined as a const
, if (i)
becomes a no-op
instruction here. A smart compiler should be able to optimize away that empty if
statement.
Example: VC 2008
A non-empty {}
with if
statement:
const int i = 1;
// mov dword ptr [i], 1
if (i)
// mov eax, 1
// test eax, eax
// je wmain+35h
{
int j = 2;
// move dword ptr [j], 2
}
// ..
Empty {}
with if
statement:
const int i = 1;
// mov dword ptr [i], 1
if (i)
{
}
// ..
I just did a quick check with the following piece of code
public class Test {
private static final boolean flag = true;
public static void main(String[] args) throws InterruptedException {
if(flag){
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
System.out.println("1");
}
}
}
when flag = true , the resulting class file size is 708
when flag = false. resulting class file size is 462
which implies that compile surely does optimization for static final values
A java compiler must detect obviously unreachable code, that's a language requirement. So the following code will compile without errors:
static final boolean flag = true;
public static void main(String[] args) {
final String msg;
if (flag)
msg = "true";
if (!flag)
msg = "false";
System.out.println(msg);
}
Note that msg is final but the compiler does neither complain that msg is not initialized nor does it complain that it gets initialized twice. Most compilers will not write dead code to the class file. But even if, the JIT will optimize it away.
C++ also has a notion of compile time constants. A const int is a compile time constant, so it can be used as a nontype template argument for example. So every sane C++ compiler will detect and optimize away obviously dead code of this type, even if you compile without specifying optimization options.
First off, Java doesn't allow non-boolean in conditionals like C (if
, while
etc.). Also, if you have a "constant" expression" in your if
checks, the compiler will warn you that you are comparing identical expressions so I'm sure it's optimized out. E.g.
final int i = 1;
if (1 == i) { // warning
System.out.println("HI");
}