Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't "i := i + 1" give a range-check error for Integers and larger types?

Consider:

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

If I declare i as Byte, Word, Shortint or TinyInt I get a range-check error, as expected. If I declare i as LongWord, Cardinal, Integer, LongInt or Int64 it just goes through the while loop and gets to show the negative or 0 value, which i gets when you pass the upper bound.

Does Delphi 7 not support range checking for 32-bit and 64-bit numbers?

like image 495
Pieter B Avatar asked Apr 18 '12 08:04

Pieter B


1 Answers

The operation i + 1 doesn't actually produce a range check error. The assignment operation does.

Delphi evaluates the constant '1' as an Integer and so the right hand side will produce a result that is either an Int64 or an Integer (The larger of i's type and Integer).

If we expand the line out we get the following

temp := i + 1 
i := temp

temp will either be 32 or 64 bits, and will overflow if it hits the upper bound. By the time we do the assignment, we have a perfectly valid 32 or 64bit value so there's no possibility of a range check failure if i is 32bits or more.

If i is less than 32 bits, it will raise a range check if temp is too large to fit.

For i >= 32bits, you can catch the overflow error like so:

{$R+,Q+}
...
like image 199
JamesT Avatar answered Sep 28 '22 08:09

JamesT