2012-04-18 9 views
14

Rozważmy:Dlaczego "i: = i + 1" nie daje błędu sprawdzania zakresu dla liczb całkowitych i większych typów?

{$R+} 
i:= 1; 
While i > 0 do 
    i:= i + 1; 
ShowMessage(IntToStr(i)); 

Jeśli oświadczam i jako Byte, Word, Shortint lub TINYINT pojawia się błąd zakres sprawdzić, jak oczekiwano. Jeśli zadeklaruję i jako LongWord, Cardinal, Integer, LongInt lub Int64, po prostu przejdzie przez pętlę while i wyświetli wartość ujemną lub 0, którą uzyskuje i po przekroczeniu górnej granicy.

Czy Delphi 7 nie obsługuje sprawdzania zakresu pod kątem liczb 32-bitowych i 64-bitowych?

Odpowiedz

13

Operacja i + 1 w rzeczywistości nie powoduje wystąpienia błędu sprawdzania zakresu. Operacja przypisania ma.

Delphi oblicza stałą "1" jako liczbę całkowitą, a więc prawa strona wygeneruje wynik o wartości Int64 lub Integer (większy z typu i Integer).

Jeśli poszerzyć linię out otrzymujemy następujące

temp := i + 1 
i := temp 

temp będzie albo 32 lub 64 bitów, a wyleje jeśli natrafi górną granicę. Do czasu, gdy wykonamy zadanie, mamy całkowicie poprawną wartość 32 lub 64-bitową, więc nie ma możliwości niepowodzenia sprawdzania zasięgu, jeśli mam 32 bity lub więcej.

Jeśli i ma mniej niż 32 bity, podniesie zakres sprawdzania, jeśli temperatura jest zbyt duża, aby zmieścić.

Na I> = 32-bitowego, można złapać błąd przepełnienia tak:

{$R+,Q+} 
... 
+0

Dzięki za wyjaśnienie co pomogło z jakimś kierunku. Zrobiłem więcej testów, zamiast dodawać i + 1 dodałem i + j zarówno z i i j tego samego typu. To spowodowało ten sam problem. Powiedziałbym więc, że operator "+" sprawia, że ​​wynik jest liczbą całkowitą. Co dziwne: jeśli używam Inc (i), to bez względu na to, jakiego typu używam, nie otrzymuję błędu rangecheck. Znalazłem {$ Q +}, aby dać mi wyjątek przepełnienia liczby całkowitej. –

+0

Przepraszam, tak, to powinno być Q, a nie O :) – JamesT

+2

Więc w końcu użyłem niewłaściwego narzędzia do pracy i powinienem był szukać przelewu zamiast rangecheck. –

Powiązane problemy