Delphi: How do i use $OVERFLOWCHECKS OFF to disable overflow checks?
Asked Answered
A

1

7

i have bit of code that causes an underflow:

var
    t1, t2, delta: DWORD:
begin
   t1 := 0xffffff00;
   t2 := 0x00000037;

   delta := (t2 - t1);

The subtraction itself does generate an overflow (underflow), but i don't want Delphi to throw an EIntOverflow exception. So i try disabling the generation of overflow checking code by disabling overflow checking:

var
    t1, t2, delta: DWORD:
begin
   t1 := 0xffffff00;
   t2 := 0x00000037;

{$OVERFLOWCHECKS OFF}
   delta := (t2 - t1);
{$OVERFLOWCHECKS ON}

Yet even with the OVERFLOWCHECKS OFF option, it still throws an exception. And the generated code still contains the check:

alt text

A reminder of the documentation on $Q:

Overflow checking

Type Switch
Syntax {$Q+} or {$Q-}
{$OVERFLOWCHECKS ON} or {$OVERFLOWCHECKS OFF}
Default {$Q-}
{$OVERFLOWCHECKS OFF}
Scope Local

Remarks

The $Q directive controls the generation of overflow checking code. In the {$Q+} state, certain integer arithmetic operations (+, -, *, Abs, Sqr, Succ, Pred, Inc, and Dec) are checked for overflow. The code for each of these integer arithmetic operations is followed by additional code that verifies that the result is within the supported range. If an overflow check fails, an EIntOverflow exception is raised (or the program is terminated if exception handling is not enabled).

The $Q switch is usually used in conjunction with the $R switch, which enables and disables the generation of range-checking code. Enabling overflow checking slows down your program and makes it somewhat larger, so use {$Q+} only for debugging.

How do i use $OVERFLOWCHECKS OFF to disable the generation of overflow checking code?


Mason's answer worked. The revised code is:

var
    t1, t2, delta: DWORD:
begin
   t1 := 0xffffff00;
   t2 := 0x00000037;

   delta := Subtract(t2, t1);


{$OVERFLOWCHECKS OFF}
function Subtract(const B, A: DWORD): DWORD; //subtract B-A
begin
   {
      Disabling overflow checking does not work at the line level,
      only the routine level. 
      Hence the function to subtract two numbers.
   }
   Result := (B-A);
end;
{$OVERFLOWCHECKS ON}

For google crawler, alternate question phrasing: How to temporarily disable overflow checking in Delphi?

Assyria answered 10/3, 2010 at 15:49 Comment(0)
G
14

It doesn't work at the line level. You need to turn it off for the entire function.

Gooden answered 10/3, 2010 at 15:57 Comment(4)
i'd be very interested to see the documentation on this and other other compiler options - specifically $RANGECHECKS... But +1 "This answer is useful)Assyria
Range checking does work on the line level. Overflow checking only works at the function level. Whichever setting is in effect at the time the compiler reaches the end will be the one used to generate the entire function's machine code. It's not documented that way, but that's the way it's worked forever. Optimization also only works at the function level; that's documented.Reformer
I got here from some Delphi code that was using {$Q+/-} at the line level. By switching to {$OVERFLOWCHECKS ON/OFF} as mentioned in the reply above, but using them to surround the entire function as this reply points out, I was able to turn off overflow checking. However, I had to remove the line level {$Q+/-} compiler directives that were already there or I still got overflow Exceptions.Coonskin
According to the documentation "delphibasics.co.uk/RTL.asp?Name=$OverFlowChecks", the option is "{$OverFlowChecks Off}" and should be specified only once at beginning of the function or procedure. I tried it and it worked for me.Gorcock

© 2022 - 2024 — McMap. All rights reserved.