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

1

16

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?

Neale answered 18/4, 2012 at 8:53 Comment(1)
See more on Range Checking here: #10135158Marsala
G
14

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+}
...
Girlie answered 18/4, 2012 at 9:38 Comment(6)
Thanks for your explanation which helped with some direction. I did some more testing, instead adding i+1 I added i+j with both i and j of the same type. This resulted in the same problem. So I'd say the "+" operator makes the result an integer. Strangely though: if I use Inc(i), then no matter what type I use, I don't get a rangecheck error. I found the {$Q+} to give me an integer overflow exception.Neale
Sorry, yes, that should have been a Q, not an O :)Girlie
So in the end I was using the wrong tool for the job and should have been looking for an overflow instead of a rangecheck.Neale
Just linking some documentation about Q+: delphibasics.co.uk/RTL.asp?Name=$QMarsala
Also noting that EVERYONE should have those two options (R and Q) turned on in project's settings when in Debug mode.Marsala
@PieterB -> It is not the = or the + operator that is doing the range/overflow checking, but some "secret" checking code that the compiler injects around those operators when the R and Q are enabled. This statement might be obvious and well known for some, but not for all - so I thought it is better to clarify it here.Marsala

© 2022 - 2024 — McMap. All rights reserved.