Andreas Kirschbaum, an open source developer, found a bug in the Java Language Specification. The bug is related to the description of definite assignment in the context of for-loops in the JLS.
The chapter that is wrong is ↗16.2.12 for Statements. It claims:
- V is definitely unassigned before the condition part of the
forstatement iff all of the following conditions hold:
- V is definitely unassigned after the initialization part of the
forstatement.- Assuming V is definitely unassigned before the condition part of the
forstatement, V is definitely unassigned after the contained statement.- Assuming V is definitely unassigned before the contained statement, V is definitely unassigned before every
continuestatement for which theforstatement is the continue target.
↗The Java Language Specification, 3rd Edition, 16.2.12 for Statements. Note: iff
is not a mistake but the specification's short hand for if and only if
.
Behold the strongly emphasized statement and think about it in the context of the following two code examples:
int foo;
for (;Math.random() < 0.5;) {
foo = 42;
} |
int foo; for (;Math.random() < 0.5; foo = 42); |
Clearly, noone would really expect these two examples to behave differently. But the strongly empasized statement claims so. For the first example, it claims that, if no other rule applies, foo will no longer be definitely unassigned, that foo is [un]assigned
in JLS terms. For the second example it claims that foo still is definitely unassigned.
Back to the JLS. What's wrong? The JLS claims that if a variable was definitely unassigned before a for statement, there are some situations where the very same variable will still be definitely unassigned at certain points in or after the for statement. The JLS claims that there are certain situations that a variable will be definitely unassigned before the condition part of the for statement. That's what's cited above. It correctly takes into account the contained statement, but it ignores the incrementation part. The JLS should be changed to:
- V is definitely unassigned before the condition part of the
forstatement iff all of the following conditions hold:
- V is definitely unassigned after the initialization part of the
forstatement.- Assuming V is definitely unassigned before the condition part of the
forstatement, V is definitely unassigned after the contained statement and after the incrementation part.- Assuming V is definitely unassigned before the contained statement, V is definitely unassigned before every
continuestatement for which theforstatement is the continue target.
Looking closer at it, the third conditional statement also looks bogus:
- V is definitely unassigned before the condition part of the
forstatement iff all of the following conditions hold:
- V is definitely unassigned after the initialization part of the
forstatement.- Assuming V is definitely unassigned before the condition part of the
forstatement, V is definitely unassigned after the contained statement.- Assuming V is definitely unassigned before the contained statement, V is definitely unassigned before every
continuestatement for which theforstatement is the continue target.
Behold the strongly emphasized statement and think about it in the context of the following two code examples:
int foo;
for (;Math.random() < 0.5;) {
foo = 42;
continue;
} |
int foo; for (;Math.random() < 0.5; foo = 42) continue; |
In both cases, foo is assigned a value if the contained statement executes. But again, the JLS fails to realize that the assignment state of foo before the condition part of the for statement might not only be changed by the contained statement itself, but also by the incrementation part. Thus that part of the JLS should be changed to, now taking into account the incrementation part for both, continue statements and the contained statement as such:
- V is definitely unassigned before the condition part of the
forstatement iff all of the following conditions hold:
- V is definitely unassigned after the initialization part of the
forstatement.- Assuming V is definitely unassigned before the condition part of the
forstatement, V is definitely unassigned after the contained statement.- Assuming V is definitely unassigned before the contained statement, V is definitely unassigned before every
continuestatement for which theforstatement is the continue target.- Assuming V is definitely unassigned before the incrementation part, V is definitely unassigned after the incrementation part.
Cher, 2006-10-28.
Cher is a computer hacker that actively contributes to open source software and also runs some of his own projects as open source.
Cher's homepage is ↗http://www.riedquat.de/.
Andreas Kirschbaum is an open source developer. He found the bug described in this blog entry and discussed it with Cher. Some of the projects he actively contributes to are ↗Crossfire and ↗Gridarta.
The Java Language Specification is the official and only specification of the Java Programming Language.
The Java Language Specification can be found online at ↗http://java.sun.com/docs/books/jls/.