Перехват исключения целочисленного переполнения в FreePascal

Я пытаюсь использовать эту простую программу для обнаружения исключений.

Исключение деление на ноль успешно перехвачено. Однако я не могу поймать целочисленное переполнение.

Я понимаю, что целое число типа SmallInt переполняется после +32767, поскольку наибольшее значение со знаком = 2^15 - 1 (т. е. +32767).

Вот код:

Program ss;

Var

  Price, Qty: SmallInt;
  Rate: Real;

Begin
  Try

    write('Enter Total price '); Readln(Price);
    Write('Enter qty '); Readln(Qty);

    Rate := Price / Qty;
    Writeln('Single item = ', Rate:0:2);

  except
    On EDivByZero Do Writeln('qty must be a valid num above 0');
    On EIntOverflow Do Writeln('too large')
  end;
End.

Однако похоже, что исключение переполнения не перехвачено. Скорее, значение переполнения принимается как отрицательное число, и код продолжается, как будто все в порядке.

Вот результат:

Введите общую стоимость 32768

Введите количество 1

Один элемент = -32768,00

Нажмите любую клавишу, чтобы вернуться в IDE

Я что-то не так делаю в коде? Каков правильный метод отлова целочисленного переполнения в FreePascal?

Спасибо!


person itsols    schedule 07.01.2016    source источник
comment
Я не эксперт в Free Pascal, но я предполагаю, что исключение переполнения вызывается только в результате вычисления. Деление на 1 не меняет значение, поэтому не генерируется исключение. Попробуйте добавить, вычесть или умножить значения, которые находятся в диапазоне, но результат операции выходит за его пределы. Например х := 32767; х := х+1   -  person Stuart    schedule 07.01.2016
comment
@Stuart Спасибо за ваш вклад. Я попытался умножить 17000 на 2 и сохранить его в SmallInt. Он дал вывод как -31536. Другими словами, он переполняется, но не сталкивается с кодом обработки исключений.   -  person itsols    schedule 07.01.2016
comment
Почему бы вам не попробовать код, который я предложил. 17000 * 2, вероятно, будет выполняться как целочисленное умножение, и когда вы сохраняете результат в smallint, он затем усекается до smallint. Усечение целого числа не является вычислением, поэтому оно может не генерировать исключение целочисленного переполнения.   -  person Stuart    schedule 07.01.2016
comment
@Stuart В вашем примере вывод равен -32768 (значение переполнения), и исключение не запускается. Я припоминаю, что какой-то старый язык (кажется, это был VB6, но я не могу подтвердить это прямо сейчас), дающий аналогичный результат. Спасибо еще раз.   -  person itsols    schedule 07.01.2016


Ответы (1)


Вы должны включить модуль sysutils, так как он содержит код, который превращает самые глубокие ошибки времени выполнения в перехватываемые языковые исключения.

person Marco van de Voort    schedule 07.01.2016
comment
Спасибо, Марко. Кроме включения этого устройства, нужно ли что-то еще делать? Я включил его, и он работает без каких-либо изменений. - person itsols; 07.01.2016
comment
Что бы это ни стоило, моя версия компилятора показывает 2.6.2-8 в меню «Справка» > «О программе». - person itsols; 07.01.2016