Bug 3451 - Disappearing variables (scope issue) (1GLE82V)
Summary: Disappearing variables (scope issue) (1GLE82V)
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P2 normal (vote)
Target Milestone: 2.0 M1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2001-10-10 22:55 EDT by Jared Burns CLA
Modified: 2003-03-17 11:43 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jared Burns CLA 2001-10-10 22:55:20 EDT
public class Hello() {

	public static void main(String[] args) {
		int x, y;
		x = y = 0;
		List list;
		if (x == y) {
			list= new ArrayList(1);
			list.add("Graah!");
		}
		System.out.println("Foo");
	}

}

1. Place a breakpoint on line 5 ("x = y  = 0") and begin stepping.
2. Note that "list" appears in the variables view when it is
	initialized inside the "if" statement.
3. Note that "list" disappears from the variables view when
	you step out of the "if" statement.

Changing the conditional expression to "true" or adding an
unconditional "else" after the "if" makes the list variable persist.

NOTES:

JMB (10/10/2001 3:34:19 PM)
	Note that this may be a compiler bug. I checked my compiler preferences
	and the preference "Preserve unused local variables" is selected, so the
	compiler should not be removing "list".

DW (10/10/2001 3:59:47 PM)
	I debugged, and noted that the variables view was displaying correct
	relative to what we get back from (jdi) StackFrame.visibleVariables(). The
	"list" variable appears and disappears from the visible variable list.
	
	Moved to JCORE - suspect this is a compiler issue.
Comment 1 Philipe Mulet CLA 2001-10-12 09:33:19 EDT
Please investigate
Comment 2 Olivier Thomann CLA 2001-10-22 17:50:30 EDT
This is not a bug. If you look at the code source:

import java.util.List;
import java.util.ArrayList;

public class Hello {

        public static void main(String[] args) {
                int x, y;
                x = y = 0;
                List list;
                if (x == y) {
                        list= new ArrayList(1);
                        list.add("Graah!");
                }
                System.out.println("Foo");
        }

}

If the if condition is false, then the list variable is not initialized and so 
it has no reason of being displayed outside of the if statement. In compiler 
term, the list variable is *not* definitely assigned after the if statement and 
this is why it has been removed from the list of visible variables.

If you write a code that uses list without initializing it, you would run into a 
error: "The local variable list may not have been initialized". For example, try 
to compile:
[import java.util.List;
import java.util.ArrayList;

public class Hello {

        public static void main(String[] args) {
                int x, y;
                x = y = 0;
                List list;
                if (x == y) {
                        list= new ArrayList(1);
                        list.add("Graah!");
                }
                System.out.println("Foo" + list);
        }

}]

The ranges in the local variable attributes are only ranges when the local is 
actually initialized and *not* when it is defined. I agree that list is defined 
after the if statement, but it may not have been initialized. This is consistent 
with the VM specs.
The VM specs state: "Each entry in the local_variable_table array indicates a 
range of code array offsets within a local variable has a value." In this case 
the variable list has no value if the if condition is false. Therefore we close 
the range. Surprisingly javac 1.3 doesn't close the range and consider list has 
been initialized till the end of the method. But if you compile the second piece 
of code, it complains that list may not have been initialized. I don't find this 
behavior very consistent.
Comment 3 Philipe Mulet CLA 2001-10-23 05:49:26 EDT
Need more investigation

What happens then if debugging the following file, and put a breakpoint
on the line with comment /// look at #list value.

If the file was compiled with Eclipse, then #list would not be available, but
if compiled with Sun, what happens since the variable has no value ?

import java.util.List;
import java.util.ArrayList;

public class Hello {

        public static void main(String[] args) {
                int x, y;
                x = y = 0;
                List list;
                if (x != y) {
                        list= new ArrayList(1);
                        list.add("Graah!");
                }
                System.out.println("Foo"); /// look at #list value
        }
}
Comment 4 Olivier Thomann CLA 2001-10-23 11:51:01 EDT
Javac 1.2.2 has the same ranges we do. Javac 1.3 and 1.4 don't. I suspect a bug, 
because we follow the specs. Now it is possible they decided to change this 
behavior, but the latest JLS and VM specs don't reflect it.
I would say that our behavior can easily be explained, because we display a 
variable only when the variable is definitely assigned and not when it is 
potentially assigned. Using a .class file compiled with javac 1.3, I could see 
the value of the local list after the if statement in the debugger. It works 
fine. But I am sure that we can have problems in some patterns.
As long as it is not possible to use a variable, I don't see why we would 
display its value. So I would close this PR. If it is really annoying for users, 
we might want to change our behavior, but then it is more difficult to explain 
why we display a variable which is not *definitely* assigned. Matching the specs 
should not be considered as a bug.
Comment 5 Olivier Thomann CLA 2001-10-23 11:51:14 EDT
Move to closed.
Comment 6 DJ Houghton CLA 2001-10-29 17:15:13 EST
PRODUCT VERSION:
2.0 stream