Параметр 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 и т. п…