[fpc-pascal] subtract longwords with rollover

Jonas Maebe jonas.maebe at elis.ugent.be
Fri Nov 29 11:50:04 CET 2013


On 29 Nov 2013, at 11:00, Klaus Hartnegg wrote:

> Explanation: I'm trying to port code from Turbo Pascal. There word1- 
> word2 does wrap around with {$Q-}{$R+}. And dec(word1) never checks  
> for overflow, even with {$Q+}{$R+}.
>
> FreePascal seems to have a wider definition of Range Check, and the  
> inc() and dec() functions do check for overflow.
>
> The longint trick prevents runtime error 201, but causes runtime  
> error 215 if the longword value does not fit into longint.
>
> On closer look this is all behaving like documented, just different  
> from TurboPascal (maybe it would have worked in TP-compatibility- 
> mode).
>
> The correct fix is to simply add {$R-} to the code wherever it  
> currently has {$Q-}. I have just done this, and now it passes the  
> test.

It's due to the fact that (then) Borland initially implemented range  
checking in an incomplete way, and didn't detect range errors that  
were caused by overflow in a register. They probably decided to add  
this to a separate check because just adding this functionality to {$R 
+} could break existing programs. However, semantically there is no  
difference between a range error and an overflow error: in both cases  
a value out of range is produced.

The reason that you sometimes get range errors in FPC while you would  
get overflow errors in TP, is because in Pascal by default all  
operations are carried out using the CPU native integer type. In TP  
this is 16 bit, in FPC 32 or 64 bit. As a result, several calculations  
that would overflow in TP become range errors in FPC.


Jonas



More information about the fpc-pascal mailing list