Delphi: How to avoid EIntOverflow underflow when subtracting?

Posted by Ian Boyd on Stack Overflow See other posts from Stack Overflow or by Ian Boyd
Published on 2010-03-10T15:06:14Z Indexed on 2010/03/12 18:27 UTC
Read the original article Hit count: 240

Microsoft already says, in the documentation for GetTickCount, that you could never compare tick counts to check if an interval has passed. e.g.:

Incorrect (pseudo-code):

DWORD endTime = GetTickCount + 10000; //10 s from now

...

if (GetTickCount > endTime)
   break;

The above code is bad because it is suceptable to rollover of the tick counter. For example, assume that the clock is near the end of it's range:

endTime = 0xfffffe00 + 10000
        = 0x00002510; //9,488 decimal

Then you perform your check:

if (GetTickCount > endTime)

Which is satisfied immediatly, since GetTickCount is larger than endTime:

if (0xfffffe01 > 0x00002510)

The solution

Instead you should always subtract the two time intervals:

DWORD startTime = GetTickCount;

...

if (GetTickCount - startTime) > 10000 //if it's been 10 seconds
   break;

Looking at the same math:

if (GetTickCount - startTime) > 10000

if (0xfffffe01 - 0xfffffe00) > 10000

if (1 > 10000)

Which is all well and good in C/C++, where the compiler behaves a certain way.

But what about Delphi?

But when i perform the same math in Delphi, with overflow checking on ({Q+}, {$OVERFLOWCHECKS ON}), the subtraction of the two tick counts generates an EIntOverflow exception when the TickCount rolls over:

if (0x00000100 - 0xffffff00) > 10000

0x00000100 - 0xffffff00 = 0x00000200

What is the intended solution for this problem?

Edit: i've tried to temporarily turn off OVERFLOWCHECKS:

{$OVERFLOWCHECKS OFF}]
   delta = GetTickCount - startTime;
{$OVERFLOWCHECKS ON}

But the subtraction still throws an EIntOverflow exception.

Is there a better solution, involving casts and larger intermediate variable types?

© Stack Overflow or respective owner

Related posts about delphi

Related posts about delphi-5