Erroneous for-loops in Java?

I'm able to reproduce it with the . Class file produced by Eclipse, but not when compiling on the command line with javac .

Up vote 23 down vote favorite 3 share g+ share fb share tw.

I observed erroneous behaviour running the following java-code: public class Prototype { public static void main(String args) { final int start = Integer. MAX_VALUE/2; final int end = Integer. MAX_VALUE; { long be = 0; for (int I = start; I Println(b); } { long be = 0; for (int I = start; I I'm running the code on Linux using Version: java version "1.6.0_25" Java(TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode) Sample Output: 1073741811 141312 Can you reproduce it?

Is it a bug? Edit: Strange final int end = Integer. MAX_VALUE - 1; works fine.

Java for-loop non-deterministic link|improve this question edited Aug 9 '11 at 11:36Björn Pollex32.1k32776 asked Aug 9 '11 at 11:10Sebastian1164.

2 There must be another error, as I get in both loops the value 1073741824 – leifg Aug 9 '11 at 11:13 3 I have reproduced this bug on a MacBook running OS X 10.6.8. – Björn Pollex Aug 9 '11 at 11:14 2 run #1: 1073741811 76800 run #2: 1073741811 77824 run #3: 1073741811 60416 run #4: 1073741811 53248 Using jdk1.6.0_25 on Windows 7 64 bit – hakon Aug 9 '11 at 11:18 2 1.6.0.24 on Windows 7, just wanted to point out taht even the first line seems not to be correct – leifg Aug 9 '11 at 11:18 2 Reproduced on MAC. Values are 1073741811 and 97280 – Sathwick Aug 9 '11 at 11:20.

I'm able to reproduce it with the . Class file produced by Eclipse, but not when compiling on the command line with javac. The bytecode generated differs: javac output public static void main(java.lang.

String); Code: 0: lconst_0 1: lstore_3 2: ldc #2; //int 1073741823 4: istore 5 6: iload 5 8: ldc #3; //int 2147483647 10: if_icmpge 23 13: lload_3 14: lconst_1 15: ladd 16: lstore_3 17: iinc 5, 1 20: goto 6 23: getstatic #4; //Field java/lang/System. Out:Ljava/io/PrintStream; 26: lload_3 27: invokevirtual #5; //Method java/io/PrintStream. Println:(J)V 30: lconst_0 31: lstore_3 32: ldc #2; //int 1073741823 34: istore 5 36: iload 5 38: ldc #3; //int 2147483647 40: if_icmpge 53 43: lload_3 44: lconst_1 45: ladd 46: lstore_3 47: iinc 5, 1 50: goto 36 53: getstatic #4; //Field java/lang/System.

Out:Ljava/io/PrintStream; 56: lload_3 57: invokevirtual #5; //Method java/io/PrintStream. Println:(J)V 60: return For something easier to read, here is the Grimp output produced by Soot: java.lang. String r0; long l0, l2; int i1, i3; r0 := @parameter0; l0 = 0L; i1 = 1073741823; label0: if i1 >= 2147483647 goto label1; l0 = l0 + 1L; i1 = i1 + 1; goto label0; label1: java.lang.System.out.

Println(l0); l2 = 0L; i3 = 1073741823; label2: if i3 >= 2147483647 goto label3; l2 = l2 + 1L; i3 = i3 + 1; goto label2; label3: java.lang.System.out. Println(l2); return; Eclipse compiler output public static void main(java.lang. String); Code: 0: ldc #16; //int 1073741823 2: istore_1 3: ldc #17; //int 2147483647 5: istore_2 6: lconst_0 7: lstore_3 8: ldc #16; //int 1073741823 10: istore 5 12: goto 22 15: lload_3 16: lconst_1 17: ladd 18: lstore_3 19: iinc 5, 1 22: iload 5 24: ldc #17; //int 2147483647 26: if_icmplt 15 29: getstatic #18; //Field java/lang/System.

Out:Ljava/io/PrintStream; 32: lload_3 33: invokevirtual #24; //Method java/io/PrintStream. Println:(J)V 36: lconst_0 37: lstore_3 38: ldc #16; //int 1073741823 40: istore 5 42: goto 52 45: lload_3 46: lconst_1 47: ladd 48: lstore_3 49: iinc 5, 1 52: iload 5 54: ldc #17; //int 2147483647 56: if_icmplt 45 59: getstatic #18; //Field java/lang/System. Out:Ljava/io/PrintStream; 62: lload_3 63: invokevirtual #24; //Method java/io/PrintStream.

Println:(J)V 66: return Grimp output: java.lang. String r0; int i0, i1, i3, i5; long l2, l4; r0 := @parameter0; i0 = 1073741823; i1 = 2147483647; l2 = 0L; i3 = 1073741823; goto label1; label0: l2 = l2 + 1L; i3 = i3 + 1; label1: if i3 = 2147483647) on an int, which shouldn't make sense (the equal does, but not the greater than). Both look correct, though, so I'd suspect a JVM bug.

There are bugs that affect for loops specifically when the upper bound is close to Integer. MAX_VALUE. See this question.

1 The Eclipse-generated bytecode seems to work just fine with end = Integer. MAX_VALUE-1, so it seems specific to Integer. MAX_VALUE indeed.

– Bruno Aug 9 '11 at 12:29.

According to the Java gurus this is bug 5091921, fixed in JDK7 but not planned for a fix in JDK6.

It is possible it is the erroneous loop unrolling in HotSpot in 64-bit server VM. Try running the code with either -client or +XX:-AggressiveOpts.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions