According to the JLS, an int
array should be filled by zeros just after initialization. However, I am faced with a situation where it is not. Such a behavior occurs
I made some change in your code. It's not a problem of Integer overflow. See the code, it throws an exception at runtime
int[] a;
int n = 0;
for (int i = 0; i < 100000000; ++i) {
a = new int[10];
for (int f : a) {
if (f != 0) {
throw new RuntimeException("Array just after allocation: " + Arrays.toString(a));
}
}
for (int ii = 0, len = a.length; ii < len; ii++)
a[ii] = 0;
for (int j = 0; j < a.length; ++j)
a[j] = Integer.MAX_VALUE - 1;
for (int j = 0; j < a.length; ++j)
n++;
}
Here we are faced with a bug in the JIT-compiler. Compiler determines that the allocated array is filled after allocation in Arrays.fill(...)
, but the check for uses between the allocation and the fill is faulty. So, compiler performs an illegal optimization - it skips zeroing of allocated array.
This bug is placed in Oracle bug tracker (bug id 7196857). Unfortunately, I did not wait for any clarifications from Oracle about the following points. As I see, this bug is OS-specific: it absolutely reproducible on 64-bit Linux and Mac, but, as I see from comments, it reproduces not regularly on Windows (for similar versions of JDK). Additionally it would be nice to know when this bug will be fixed.
There is only advice at the moment: do not use JDK1.7.0_04 or later if you depend on JLS for newly declared arrays.
Update at October 5:
In the new Build 10 of the JDK 7u10 (early access) released at October 04, 2012, this bug was fixed at least for Linux OS (I did not test for other). Thanks to @Makoto, who found that this bug is no longer available for public access in Oracle bug database. Unfortunately, I do not know for the reasons Oracle removed it from public access, but it is available in Google cache. Also, this bug has caught the attention of Redhat: the CVE identifiers CVE-2012-4420 (bugzilla) and CVE-2012-4416 (bugzilla) were assigned to this flaw.