Microsoft уже говорит в документации для GetTickCount, что вы никогда не сможете сравнить количество тиков, чтобы проверить, прошел ли интервал. e.g.:
Неправильно (псевдокод):
DWORD endTime = GetTickCount + 10000; //10 s from now
...
if (GetTickCount > endTime)
break;
Приведенный выше код неверен, так как он подходит для переключения тикового счетчика. Например, предположим, что часы близки к концу диапазона:
endTime = 0xfffffe00 + 10000
= 0x00002510; //9,488 decimal
Затем вы выполняете проверку:
if (GetTickCount > endTime)
Что удовлетворяется немедленно, поскольку GetTickCount
на больше endTime
:
if (0xfffffe01 > 0x00002510)
Решение
Вместо этого вы всегда должны вычитать два временных интервала:
DWORD startTime = GetTickCount;
...
if (GetTickCount - startTime) > 10000 //if it's been 10 seconds
break;
Глядя на ту же математику:
if (GetTickCount - startTime) > 10000
if (0xfffffe01 - 0xfffffe00) > 10000
if (1 > 10000)
Что хорошо в C / C ++, где компилятор ведет себя определенным образом.
А как же Дельфи?
Но когда я выполняю ту же математику в Delphi с проверкой переполнения ({Q+}
, {$OVERFLOWCHECKS ON}
), вычитание двух отсчетов тиков генерирует исключение EIntOverflow, когда TickCount переворачивается:
if (0x00000100 - 0xffffff00) > 10000
0x00000100 - 0xffffff00 = 0x00000200
Каково решение этой проблемы?
Редактировать: я пытался временно отключить OVERFLOWCHECKS
:
{$OVERFLOWCHECKS OFF}]
delta = GetTickCount - startTime;
{$OVERFLOWCHECKS ON}
Но вычитание все равно вызывает исключение EIntOverflow
.
Есть ли лучшее решение, включающее приведение типов и большие промежуточные типы переменных?
Обновление
Другой вопрос, который я задал, объяснил, почему {$OVERFLOWCHECKS}
не работает. По-видимому, он работает только на уровне function , а не на уровне line . Так что пока следующее не не работает:
{$OVERFLOWCHECKS OFF}]
delta = GetTickCount - startTime;
{$OVERFLOWCHECKS ON}
следующее работает работает:
delta := Subtract(GetTickCount, startTime);
{$OVERFLOWCHECKS OFF}]
function Subtract(const B, A: DWORD): DWORD;
begin
Result := (B - A);
end;
{$OVERFLOWCHECKS ON}