2016-07-25 33 views
8

Kod poniżejDlaczego jest to, że kod poniżej zachowuje się inaczej w Javie 1.6 i 1.7

public class Test16Jit { 
    public static void main(String[] s) { 
     int max = Integer.MAX_VALUE; 
     int i = 0; 
     long li = 0; 
     while (i >= 0) { 
      i++; 
      li++; 
      if (i > max) { 
       System.out.println("i is : " + i); 
       System.out.println("max is : " + max); 
       System.out.println("Woo!! something really went wrong"); 
      } 
     } 
     System.out.println("Value of i: " + i); 
     System.out.println("Total # of iterations: " + li);  
    } 
} 

wyjść poniżej w Javie 1.7x

Value of i: -2147483648 
Total # of iterations: 2147483648 

Wyjścia poniżej Java 1.6x

i is : 2147483636 
max is : 2147483647 
Woo!! something really went wrong 
Value of i: -2147483648 
Total # of iterations: 2147483648 

Czy istnieje powód takiego zachowania?

Również jeśli zmienię

int max = Integer.MAX_VALUE; -> final int max = Integer.MAX_VALUE; 

on zachowuje się dokładnie tak samo w 1,6x i 1,7x

+1

Czy otrzymujesz różnicę w zachowaniu od prostszego kodu 'int max = Integer.MAX_VALUE; int i = 2147483636; System.out.println (i> max); '? –

+1

@AndyTurner Nie testowałem, ale domyślam się, że to jest błąd JIT. – shmosel

+0

To drukuje fałszywe @AndyTurner –

Odpowiedz

7

Wydaje się, że jednym z wielu przykładów rodziny błędów związanych z tym jednym spowodowane przez kompilację JIT (I wybraliśmy ten ze względu na podobieństwa kodu, nie krępuj się badać inne - są one dość ciekawe!):

http://bugs.java.com/view_bug.do?bug_id=6196102

EWALUACJA

Problem dotyczy kanonizacji testu wyjścia pętli w przygotowaniu do transformacji pętli .

do while (++i <= limit)

staje

do while (++i < limit+1)

nie jest to poprawne, gdy granica jest MaxInt.

Niektóre problemy zostały naprawione w 1.7, co może wyjaśnić twoje wyniki.

+1

Bardzo dobre znalezisko. Jednak wciąż trochę drapię głowę, dlaczego tak się stanie na samym końcu, gdy przepełnienie będzie całkowite? –

Powiązane problemy