From: Eric Blake <###@###.###>
Date: Fri, 30 Nov 2001 17:29:53 -0700
Reply-To: ###@###.###
Subject: [Java Spec Report] Re: Final Release of JSR-41
I had a conversation off this list, where the following point was made;
and I'm not sure I agree with it.
Neal Gafter wrote:
>
> > // assignment to final parameter, should fail
> > assert true : args = null;
>
> No, it should pass for the same reason that
>
> if (false) args = null;
>
> passes.
According to JLS 4.5.4, "It is a compile time error if a final variable
is assigned to unless it is definitely unassigned (§16) immediately
prior to the assignment. ...
A blank final is a final variable whose declaration lacks an
initializer."
According to JLS 16, "Throughout the rest of this chapter, we will,
unless explicitly stated otherwise, write V to represent a local
variable or a blank final field (for rules of definite assignment) or a
blank final variable (for rules of definite unassignment)."
Also, according to JLS 15.26, "A variable that is declared final cannot
be assigned to (unless it is a blank final variable (§4.5.4)), because
when an access of a final variable is used as an expression, the result
is a value, not a variable, and so it cannot be used as the first
operand of an assignment operator."
The way I read it, a final parameter (method, constructor, or
exception-handler) has an initializer, albeit an implicit one, as the
grammar does not permit an explicit one (besides, 4.5.3 states that
these parameters are always initialized, and gives the initial value).
Therefore, I claim that a parameter cannot be a blank final, and that
any attempt to assign to a final parameter should fail for the same
reason that an attempt to assign a non-blank final field fails: the
variable is not a blank final. In short, I see no reason to perform
definite unassignment analysis on parameters.
By my interpretation, this program should fail to compile with 3 errors
(and that is the implementation jikes presently uses):
class Blah {
public static void main(final String[] args) {
if (false) args = null;
try {
throw new Exception();
} catch (final Exception e) {
if (false) e = null;
}
}
Blah(final int i) {
if (false) i = 1;
}
}
But apparently Neal feels otherwise; and javac compiles this program
without complaint. I am not sure which approach is best; can anyone
else find unambiguous quotes in the JLS to support one position or the
other? If not, then this issue deserves at least a Clarification in the
Spec Report, since compiler implementations currently differ in their
treatment of the above program.
Meanwhile, the sentence I quoted above from 16, which claims that
definite assignment analysis is not necessary for formal method,
constructor, or exception-handler parameters, makes these phrases in
16.3 invalid: "A formal parameter V of a method or constructor is
definitely assigned... An exception parameter V of a catch clause is
definitely assigned...". Whether the second part of those sentences
"(and moreover is not definitely unassigned)" is valid depends on the
outcome of the above discussion, whether a parameter can be considered a
blank final. If my interpretation is correct, then 16.3 is completely
unnecessary, as a parameter has neither DA nor DU analysis performed on
it.
Also, these two statements conflict - is a final parameter treated as a
variable, or a value?
JLS 15.26 "when an access of a final variable is used as an expression,
the result is a value, not a variable,"
JLS 6.5.6.1 "If the Identifier appears within the scope (§6.3) of a
visible local variable declaration (§14.4) or visible parameter
declaration (§8.4.1, §8.8.1, §14.19) with that name, then the expression
name denotes a variable, that is, that local variable or parameter."
Note that if a final parameter is taken as a value and not a variable
(following chapter 15, but not 6), then my above argument for
disallowing assignments to final parameters in an if(false) block
becomes even stronger. But keep in mind Spec Report 6.5.6, which claims
that treating final variables as variables is an anachronism left over
from the first edition, which should not be present in the first place.
--
This signature intentionally left boring.
Eric Blake ###@###.###
BYU student, free software programmer
Date: Fri, 30 Nov 2001 17:29:53 -0700
Reply-To: ###@###.###
Subject: [Java Spec Report] Re: Final Release of JSR-41
I had a conversation off this list, where the following point was made;
and I'm not sure I agree with it.
Neal Gafter wrote:
>
> > // assignment to final parameter, should fail
> > assert true : args = null;
>
> No, it should pass for the same reason that
>
> if (false) args = null;
>
> passes.
According to JLS 4.5.4, "It is a compile time error if a final variable
is assigned to unless it is definitely unassigned (§16) immediately
prior to the assignment. ...
A blank final is a final variable whose declaration lacks an
initializer."
According to JLS 16, "Throughout the rest of this chapter, we will,
unless explicitly stated otherwise, write V to represent a local
variable or a blank final field (for rules of definite assignment) or a
blank final variable (for rules of definite unassignment)."
Also, according to JLS 15.26, "A variable that is declared final cannot
be assigned to (unless it is a blank final variable (§4.5.4)), because
when an access of a final variable is used as an expression, the result
is a value, not a variable, and so it cannot be used as the first
operand of an assignment operator."
The way I read it, a final parameter (method, constructor, or
exception-handler) has an initializer, albeit an implicit one, as the
grammar does not permit an explicit one (besides, 4.5.3 states that
these parameters are always initialized, and gives the initial value).
Therefore, I claim that a parameter cannot be a blank final, and that
any attempt to assign to a final parameter should fail for the same
reason that an attempt to assign a non-blank final field fails: the
variable is not a blank final. In short, I see no reason to perform
definite unassignment analysis on parameters.
By my interpretation, this program should fail to compile with 3 errors
(and that is the implementation jikes presently uses):
class Blah {
public static void main(final String[] args) {
if (false) args = null;
try {
throw new Exception();
} catch (final Exception e) {
if (false) e = null;
}
}
Blah(final int i) {
if (false) i = 1;
}
}
But apparently Neal feels otherwise; and javac compiles this program
without complaint. I am not sure which approach is best; can anyone
else find unambiguous quotes in the JLS to support one position or the
other? If not, then this issue deserves at least a Clarification in the
Spec Report, since compiler implementations currently differ in their
treatment of the above program.
Meanwhile, the sentence I quoted above from 16, which claims that
definite assignment analysis is not necessary for formal method,
constructor, or exception-handler parameters, makes these phrases in
16.3 invalid: "A formal parameter V of a method or constructor is
definitely assigned... An exception parameter V of a catch clause is
definitely assigned...". Whether the second part of those sentences
"(and moreover is not definitely unassigned)" is valid depends on the
outcome of the above discussion, whether a parameter can be considered a
blank final. If my interpretation is correct, then 16.3 is completely
unnecessary, as a parameter has neither DA nor DU analysis performed on
it.
Also, these two statements conflict - is a final parameter treated as a
variable, or a value?
JLS 15.26 "when an access of a final variable is used as an expression,
the result is a value, not a variable,"
JLS 6.5.6.1 "If the Identifier appears within the scope (§6.3) of a
visible local variable declaration (§14.4) or visible parameter
declaration (§8.4.1, §8.8.1, §14.19) with that name, then the expression
name denotes a variable, that is, that local variable or parameter."
Note that if a final parameter is taken as a value and not a variable
(following chapter 15, but not 6), then my above argument for
disallowing assignments to final parameters in an if(false) block
becomes even stronger. But keep in mind Spec Report 6.5.6, which claims
that treating final variables as variables is an anachronism left over
from the first edition, which should not be present in the first place.
--
This signature intentionally left boring.
Eric Blake ###@###.###
BYU student, free software programmer
- duplicates
-
JDK-4642981 javac fails to disallow assignment to final parameter and final exception var
- Closed