Параметр Range checking
Это один из наиболее востребованных параметров при отладке приложения. Он отвечает за проверку границ при доступе к массиву данных. В самом простом случае вам будет сгенерировано исключение при выполнении вот такого кода:
const
A: array [0..1] of Char = ('A', 'B');
procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
begin
for I := 0 to 100 do
Caption := Caption + A[I];
end;
Здесь мы просто пытаемся обратится к элементу массива, и в принципе, при отключенной опции «Range checking», если мы не выйдем за границу выделенной памяти, данный код нам грозит только тем, что в заголовке формы появится некая непонятная строка.
Что неприятно, но некритично для выполнения программы.
Гораздо хуже, если вы ошиблись с границами блока при попытке записи в него – в этом случае может произойти разрушение памяти приложения. Рассмотрим такой пример, оптимизацию отключим:
type
TMyEnum1 = (en1, en2, en3, en4, en5);
TMyEnum2 = en1..en3;
procedure TForm1.FormCreate(Sender: TObject);
var
I: TMyEnum1;
HazardVariable: Integer;
Buff: array [TMyEnum2] of Integer;
begin
HazardVariable := 100;
for I := Low(I) to High(I) do
Buff[I] := Integer(I);
ShowMessage(IntToStr(HazardVariable));
end;
После выполнения данного кода число HazardVariable будет равно не 100, а 4. При написании кода мы ошиблись при выборе типа итератора и вместо TMyEnum2 написали TMyEnum1, произошел выход за диапазон границ массива и затерлись данные на стеке, изменив значения локальных переменных хранящихся на нём же.
С включенной оптимизацией ситуация будет еще хуже. Мы получим следующую ошибку:
По данному описанию мы даже не сможем предположить, где именно произошло исключение, и почему оно произошло, так как адреса, упомянутые в тексте ошибки, не принадлежат памяти приложения, и если такая ошибка возникнет у клиента – исправить ее по данному описанию мы не сможем.
Поэтому отладка приложения всегда должна происходить с включенной настройкой Range checking.
Так же данный параметр контролирует выход за границы допустимых значений при изменении значения переменных. Например, будет поднято исключение при попытке присвоения отрицательного значения беззнаковым типам наподобие Cardinal/DWORD, или при попытке присвоить значение большее, чем может содержать переменная данного типа, например, при присвоении 500 переменной типа Byte и т. п…
Параметр «I/O cheking»
Отвечает за проверку результатов ввода/вывода при работе с файлами в стиле Pascal.
Если вы работаете с Append/Assign/Rewrite и т. п., то включайте данный параметр при отладке приложения.
Параметр «Overflow cheking»
Контролирует результаты арифметических действий и поднимает исключение в тех случаях, когда результат выходит за диапазон переменной.
Чтобы было проще понять различия между данным параметром и Range checking, рассмотрим следующий код:
procedure TForm1.FormCreate(Sender: TObject);
var
C: Cardinal;
B: Byte;
I: Integer;
begin
I := -1;
B := I;
C := I;
ShowMessage(IntToStr(C - B));
end;
Данный код не поднимет исключения при включенном параметре Overflow cheking. Хоть здесь и присваиваются переменным недопустимые значения, но не производится математических операций над ними. Однако исключение будет поднято при включенном параметре «Range checking».
А теперь рассмотрим второй вариант кода:
procedure TForm1.FormCreate(Sender: TObject);
var
C: Cardinal;
B: Byte;
begin
B := 255;
Inc(B);
C := 0;
C := C - 1;
ShowMessage(IntToStr(C - B));
end;
Здесь уже не будет реакции от параметра Range checking, но произойдет поднятие исключения EIntegerOverflow, за который отвечает Overflow cheking, на строчках Inc(B) и C := C - 1 из-за того, что результат арифметической операции не может быть сохранен в соответствующей переменной.
Таким образом, при работе с переменными оба параметра взаимодополняют друг друга. Overflow cheking не настолько критичен, как Range checking, но всё же желательно держать его включенным при отладке приложения.
Примечание. Если вы реализуете криптографические алгоритмы, то в них, как правило, операция переполнения является штатной. В таких ситуациях выносите код в отдельный модуль и в начале модуля прописывайте директиву {$OVERFLOWCHECKS OFF} для отключения проверки переполнений в текущем модуле.
Чтобы установленные на вкладке опции вступили в силу, нужно заново выполнить сборку проекта.
Дата добавления: 2015-09-07; просмотров: 932;