-
Bug
-
Resolution: Fixed
-
P4
-
1.1.3
-
None
Prior to the JDK 1.1 language changes, the notion of definite
assignment applied only to local variables, which are always contained
within a single constructor, method, or static initializer. The
introduction of blank final class variables introduced the notion of
definite unassignment and extended the notion of definite assignment
to apply to these variables.
The definition of definite assigment in the JLS is formally
convenient, but can lead to misleading diagnostics when considered in
isolation. According to JLS 16, all variables are definitely assigned
after a statement that cannot complete normally. This is explicitly
stated in 16.2.11 for break, continue, return, and throw statements,
and may be inferred for the statement { while(true){} }. Thus the
following program would be legal:
class B {
static final int x;
static { while (true) {} } // cannot complete normally
static { System.out.println(x); }
}
This is problematic, because it is quite obvious that 'x' has not
explicitly been given a value. For a larger but similar example, it
may not be so clear that the use of the variable in the second static
initializer will be executed.
A reachable statement analysis is implicitly performed by the definite
assignment analysis, which essentially loses all information about the
variables after a statement that cannot complete normally. That this
has in fact happened, however, gives us the information we need to
make sense of the resulting diagnostics. If the compiler had issued
an error message to the effect that the second static initializer
could not be reached, then the absence of an error message regarding
the definite assignment status of 'x' would make more sense.
According to JLS 14.19, "The block that is the body of a constructor,
method, or static initializer is reachable." Thus we are at present
forbidden to reject the program above, even though is contains a most
glaring example of the class of programming error which the compile-time
flow analysis is intended to guard against.
A similar issue arises for instance variables and instance initializers.
william.maddox@Eng 1997-07-11
assignment applied only to local variables, which are always contained
within a single constructor, method, or static initializer. The
introduction of blank final class variables introduced the notion of
definite unassignment and extended the notion of definite assignment
to apply to these variables.
The definition of definite assigment in the JLS is formally
convenient, but can lead to misleading diagnostics when considered in
isolation. According to JLS 16, all variables are definitely assigned
after a statement that cannot complete normally. This is explicitly
stated in 16.2.11 for break, continue, return, and throw statements,
and may be inferred for the statement { while(true){} }. Thus the
following program would be legal:
class B {
static final int x;
static { while (true) {} } // cannot complete normally
static { System.out.println(x); }
}
This is problematic, because it is quite obvious that 'x' has not
explicitly been given a value. For a larger but similar example, it
may not be so clear that the use of the variable in the second static
initializer will be executed.
A reachable statement analysis is implicitly performed by the definite
assignment analysis, which essentially loses all information about the
variables after a statement that cannot complete normally. That this
has in fact happened, however, gives us the information we need to
make sense of the resulting diagnostics. If the compiler had issued
an error message to the effect that the second static initializer
could not be reached, then the absence of an error message regarding
the definite assignment status of 'x' would make more sense.
According to JLS 14.19, "The block that is the body of a constructor,
method, or static initializer is reachable." Thus we are at present
forbidden to reject the program above, even though is contains a most
glaring example of the class of programming error which the compile-time
flow analysis is intended to guard against.
A similar issue arises for instance variables and instance initializers.
william.maddox@Eng 1997-07-11
- relates to
-
JDK-4063938 Compiler reports unreachable static initializers, contrary to JLS
- Closed