-
Bug
-
Resolution: Fixed
-
P4
-
1.3.0
-
merlin
-
generic
-
generic
Name: boT120536 Date: 12/08/2000
java version "1.3.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_01)
Java HotSpot(TM) Client VM (build 1.3.0_01, mixed mode)
The specification for 15.28, Constant Expressions, has a number of bugs.
1. You have omitted the fact that ParenthesizedExpressions are valid constant
expressions. This is obviously allowable, though, since you then list
(short)(1*2*3*4*5) as an example constant.
2. The last two bullets are misleading. They should be amended to read:
"Simple names that refer to final primitives or Strings whose initializers are
constant expressions.
"Qualified names of the form TypeName . Identifier that refer to final
primitives or Strings whose initializers are constant expressions."
As they stand now, I could argue that the following should be legal Java (in
fact, I had submitted this as a bug to the compiler department, and was told I
was in error, and to refer the matter to specification):
class Bad {
static final Object o = "This is a constant initializer";
void foo(int i) {
switch (i) {
case (String)o != "This string is constant" ? 1 : 2: // case 1
}
}
}
As you can see, I used only a cast to String, a simple named reference to a
final variable whose initializer was a constant, the != operator, a string
literal, two integer literals, and the ?: operator, all valid by bullets in the
list of 15.28. Without the addition of an explicit statement that all
subexpressions, such as the field accesses, must also be primitives or type
String, this class file meets all the written specs for compilation, even though
it violates the spirit of the section.
3. You need to specify how to handle integer division by constant 0. 1/0 is
composed solely of elements that form constants, but cannot be a constant itself
since it is undefined. However, should it be a compile-time error to have a
constant 0 as the divisor to integer /, %, /=, and %=? Or should compilers do
as javac 1.3 does, and compile it as a non-constant and generate the guaranteed
ArithmeticException?
Personally, I would prefer that any attempt to do integer division by a constant
0 should be flagged as a compile-time error. If it is allowed to compile, then
you are violating the premise that all expressions can complete normally, since
you would be guaranteed an abrupt completion on that expression.
class Divide {
void foo(int i) {
int j = i / 0;
System.out.print(j); // this statement is unreachable
}
}
4. You should probably clarify the behavior of the short-circuiting logic
operators, when the condition is constant. Must the unevaluated portion of the
expression be constant for the overall expression to be constant? If bytecode
is generated for the unused side of the operator, it will never be called.
class ShortCircuit {
void foo(int i) {
boolean t = true, f = false;
switch (i) {
case (true || t) ? 0 : 1: // case 0
case (false && f) ? 0 : 1: // case 1
case true ? 2 : i: // case 2
case false ? i : 3: // case 3
}
}
}
5. Presumably, constant expressions can alter what exceptions an expression may
throw. I am assuming that this code should be illegal, as all the catch blocks
are provably unreachable. However, I could not find any definitive mention in
the specs one way or another as to the correctness of my assumptions. Javac 1.3
compiles this, but has other known bugs with not noticing unreachable catch
blocks.
class Question {
void foo() {
try {
String s = "a" + "b"; // cannot throw OutOfMemoryError, as the class
// file only sees this as "ab"
} catch(OutOfMemoryError e) {
}
try {
int[] i = new int[1]; // cannot throw NegativeArraySizeException, as
// the size is positive
char c = 'c';
int[] j = new int[c]; // ditto
} catch(NegativeArraySizeException e) {
}
try {
int i = 1;
int j = i / 1; // cannot throw ArithmeticException
} catch (ArithmeticException e) {
}
}
}
Likewise, code such as new int[-1] should be a compile-time error, rather than
waiting until runtime to throw the NegativeArraySizeException.
(Review ID: 113476)
======================================================================
- relates to
-
JDK-4475252 constant expr limits neglected by vmspec/ 4.10 Limitations
-
- Resolved
-