aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Compilation problem with if condition Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Compilation problem with if condition" Watch "Compilation problem with if condition" New topic
Author

Compilation problem with if condition

Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17

This compiles fine, where as



this is giving compilation error.
Why?

As per my understanding both of them should give compilation error
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

in this case, using a constant in the IF statement, the compiler can evaluate that and knows the execution path will initialize i
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Tim McGuire wrote:in this case, using a constant in the IF statement, the compiler can evaluate that and knows the execution path will initialize i

So you mean to say that line no:3 has no effect. Complier ignores line no: 3. Am I right?
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

http://java.sun.com/docs/books/jls/second_edition/html/defAssign.doc.html

In fact, the if(true) statement will not even make it into the generated bytecode. To prove this, decompile your class with the if(true) statement and you will see that the if statement has disappeared.
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

So you mean to say that line no:3 has no effect. Complier ignores line no: 3. Am I right?


In the first example line 3 will be erased by the compiler. So, yes, it has no effect.
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Tim McGuire wrote:

In the first example line 3 will be erased by the compiler. So, yes, it has no effect.


I am not sure whether this is correct. See the following example.

Where as


If compiler erase if(true) statement, then it should give error for second case also.
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Nagendrakumar Mavuri wrote:
Tim McGuire wrote:

In the first example line 3 will be erased by the compiler. So, yes, it has no effect.


I am not sure whether this is correct. See the following example.

Where as


If compiler erase if(true) statement, then it should give error for second case also.


I tested this and decompiled it and this is what I found.

I took this code:



The compiler in this case makes an if....else structure like:



so when we try your example of if true:

the compiler will first make an if ... else structure.
and then see that the else can never be reached and does away with it and the if statement and is left with:

So, I think the answer is that it is able to compile because it surrounds the "any sort of code" with an if .... else statement and then does away with it.
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Tim McGuire wrote:
the compiler will first make an if ... else structure.
and then see that the else can never be reached and does away with it and the if statement and is left with:

So, I think the answer is that it is able to compile because it surrounds the "any sort of code" with an if .... else statement and then does away with it.



If that is the case then why it is giving an error in the first post.

Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Nagendrakumar Mavuri wrote:
If that is the case then why it is giving an error in the first post.





you said your first post did not give an error.

this code above, assuming the # sign is a typo, does not give an error.
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Nagendrakumar Mavuri wrote:
If that is the case then why it is giving an error in the first post.

In the openings post he says that that compiles just fine and this doesn't:

Which can be solved by making the variables final
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Wouter Oet wrote:
Which can be solved by making the variables final


I know how to fix it, but why it is giving error. My main question was why if(true) is behaving differently in different positions.
appu sharma
Ranch Hand

Joined: Sep 20, 2009
Posts: 104

Well nagendra it is a good question.
First of all you know that unreachable code in java gives compile time error.
So let us 3 case
1.


2.

3.

I think you are satisfied now???


It doesn't matter if you win by an inch or a mile; winning's winning.
KrishnaPrasad raghavan
Ranch Hand

Joined: Oct 28, 2008
Posts: 46
Well, the bottom line

Variables declare inside a method should be initialized
This code compiles cos the instance variables need not be initialized.


But the following will throw an exception

Here the "i" needs to initialized.

Even this is initialize


Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

A variable can only be used if it is sure that it will be definitely assigned before being used.
If the compiler is not sure at compile time then the code will not compile.
In the code visually it is clear that the expression will be true but because compiler will not be sure at compile time so the code will not compile.
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Harpreet Singh janda wrote:A variable can only be used if it is sure that it will be definitely assigned before being used.
If the compiler is not sure at compile time then the code will not compile.
In the code visually it is clear that the expression will be true but because compiler will not be sure at compile time so the code will not compile.


Harpeet,

So you want to say that, when we write if(true), compiler knows that the code in the if block will be executed so it is not giving any error for the first example.


If so then why the following code is executing fine

So as per your explanation, throw new Exception will execute every time, so it should give compilation problem, at the code below it.
Neha Daga
Ranch Hand

Joined: Oct 30, 2009
Posts: 504
did you try adding a code below and compile? I think it will give compiler error if the next statement is within if block and a compiler warning if its outside if block.
the first code(if(x,y)) gives you compiler error because its not sure that initialiation statement of i within if will execute or not. and it wants to prevent you from using i without being initialised in case if condition is false.


SCJP 1.6 96%
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Nagendrakumar Mavuri wrote:

If so then why the following code is executing fine

So as per your explanation, throw new Exception will execute every time, so it should give compilation problem, at the code below it.


I think I explained this completely. The compiler is able to determine the execution path because you use a boolean constant in the if statement. As a preliminary step, you can think of the compiler establishing an if.... else structure around your code:


since the if statement always evaluates to true, the compiler erases both the if statement and the code that will never get executed in the else statement, leaving only


it is a little weird, I know.
Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Tim,


This will not give a compilation error, where as

will give a compilation error.

As per your explanation both of them are same.
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Nagendrakumar Mavuri wrote:

As per your explanation both of them are same.


They are both the same except the compiler cleans up all the unreachable code when you use if(true). This includes the code after the end of the if block

check out what the compiler does with the following code:



it recognizes that the method is going to be over at the end of the else clause, so it pulls the last line inside the else clause.



here is the resulting java code after the compiler has "optimized it"
Fribag.jad:

Notice that it has pulled "System.out.println("Hello");" INSIDE the else and thrown in a return statement. This is the compiler at work.


I think it is right to assume it does the same for your example:


that is, it pulls the int i=0; inside the else in its effort to optimize.

when we do not use if(true)
in this:


the compiler sees no path to optimize and instead reports unreachable code.

Nagendrakumar Mavuri
Greenhorn

Joined: Feb 01, 2010
Posts: 17
Thanks for the explanation Tim.

But I think I am not fully satisfied.
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Nagendrakumar Mavuri wrote:Thanks for the explanation Tim.

But I think I am not fully satisfied.


It seems a little crazy to me too. I'm just reporting what I'm seeing in the decompiler.
Rashad King
Greenhorn

Joined: Jan 31, 2010
Posts: 1
Just a thought, assuming that i and k are initialized as member variables, this would give a compiler error. Using static references in the main, since the main is static. Adding static to the local variables, such as i, j,etc. will allow the compiler to validate the code. Keep in mind, that a boolean value can only be true or false and in an if construct true is a valid expression for an if block. Just a thought.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19059
    
  40

Tim McGuire wrote:
Nagendrakumar Mavuri wrote:Thanks for the explanation Tim.

But I think I am not fully satisfied.


It seems a little crazy to me too. I'm just reporting what I'm seeing in the decompiler.



The failure of the compiler to correctly detect unreachable code, when the "if" condition is involved, is not due to the optimizer. It is actually defined in the JLS to be like that.

In the Java Language Specification, it actually defines what should be done (hypothetical) and what is done (actual) for the "if" statement. The unreachability tests for the "if" statement is purposely weaken, in order to allow for conditional code. This way, you can turn on or off debugging code, and not have the compiler complain the code inside the "if" or "else" block is unreachable.

Henry

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Henry Wong wrote:
Tim McGuire wrote:
Nagendrakumar Mavuri wrote:Thanks for the explanation Tim.

But I think I am not fully satisfied.


It seems a little crazy to me too. I'm just reporting what I'm seeing in the decompiler.



The failure of the compiler to correctly detect unreachable code, when the "if" condition is involved, is not due to the optimizer. It is actually defined in the JLS to be like that.

In the Java Language Specification, it actually defines what should be done (hypothetical) and what is done (actual) for the "if" statement. The unreachability tests for the "if" statement is purposely weaken, in order to allow for conditional code. This way, you can turn on or off debugging code, and not have the compiler complain the code inside the "if" or "else" block is unreachable.

Henry


So, you mean something like:



I understand now why you would need to relax the unreachable code rules in case of an if.

I'm not sure this fully explains why it pulls lines of code that are clearly outside of the if into the if....else block and then adds a return statement.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19059
    
  40

Tim McGuire wrote:
I'm not sure this fully explains why it pulls lines of code that are clearly outside of the if into the if....else block and then adds a return statement.



Now, this is a different question entirely... The optimizer does many many things. Code motion. Loop unrolling. Inlining. Etc. Etc. Etc. Personally, I just regard this as black magic, and just assumes it works. Sorry.

Henry
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

Harpreet Singh janda wrote:A variable can only be used if it is sure that it will be definitely assigned before being used.


Jus a point,
compare this:



to this:


My Website: [Salvin.in] Cool your mind:[Salvin.in/painting] My Sally:[Salvin.in/sally]
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

Instance variables are automatically initialized to default value, even if you do not initialize them.
So i will be initialize to 0;

salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

Harpreet Singh janda wrote:Instance variables are automatically initialized to default value, even if you do not initialize them.
So i will be initialize to 0;

which contradicts what you previously mentioned
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

A variable must be initialize before being used in the code, this is the meaning of "definitely assigned'. So if you are not initializing the instance variable explicitly then it will be automatically initialized(means will be assigned a default value when they will be declared) but the same is not true for local (method ) variables.

So you can use the instance variable without explicitly initializing them.

In your code variable i will be automatically initialized to 0 means it will be "definitely assigned' hence you can use it in the code.
 
Consider Paul's rocket mass heater.
 
subject: Compilation problem with if condition