Отключите проверку диапазона Delphi только для небольшой части кода
Как можно отключить проверку диапазона для части файла. Выключить легко, но как мне позже вернуться к настройкам проекта? Псевдокод ниже должен объяснить это:
Unit1;
//here's range checking on or off as per the project setting
code here...
{$R-}
//range checking is off here because the code causes range check errors
code here...
//now I want to revert to the project setting. How do I do that?
code here...
end.
3 ответа
Смотрите: директива IFOPT.
{$IFOPT R+}
{$DEFINE RANGEON}
{$R-}
{$ELSE}
{$UNDEF RANGEON}
{$ENDIF}
//range checking is off here because the code causes range check errors
//code here...
{$IFDEF RANGEON}
{$R+}
{$UNDEF RANGEON}
{$ENDIF}
Оберните ваш код в $R
директивы:
{$R-} // disable range checking
// do non-range-checked operations here
{$R+} // turn range checking back on
Обратите внимание, что директива применяется на уровне операторов. Вы не можете обернуть это только частью выражения.
Почему вы хотите отключить его для релизных сборок? - дан-гф
Я видел слишком много программистов Delphi, пишущих довольно большие программы, никогда не активируя проверку диапазона, переполнения и утверждения. Конечно, вы можете сделать это, если хотите, но ваш код будет более глючным.
Я надеюсь убедить больше программистов включить эти 3 проверки прямо сейчас, чтобы сделать программу более надежной.Однако обратите внимание, что за это приходится платить: ваша программа будет работать медленнее. Ниже я покажу некоторое сравнение реального времени выполнения кода с проверкой диапазона и без нее.
дело в том, что вы можете отключить его локально, где вам нужно, с помощью {$R-}. Но вы можете оставить его включенным глобально в настройках проекта — dan-gph
Лично у меня рядом с Debug и Release есть 3-й вариант PreRelease. На самом деле это отладочная версия с одним отличием: «Оптимизация» включена. Это достаточно быстро, пока он все еще выполняет проверку (диапазон, переполнение, утверждения и т. д.). Я выпускаю такую версию для ограниченного числа (~1000) клиентов. Если через неделю все выглядит хорошо, я заменяю ее на настоящую версию Release, где проверки отключены.
Проверка переполнения
Это проверит определенные целочисленные арифметические операции (+, -, *, Abs, Sqr, Succ, Pred, Inc и Dec) на переполнение. Например, после операции + (сложение) компилятор вставит дополнительный двоичный код, который проверяет, находится ли результат операции в поддерживаемом диапазоне.
«Целочисленное переполнение» происходит, когда операция над целочисленной переменной дает результат, выходящий за пределы диапазона этой переменной. Например, если целочисленная переменная объявлена как 16-разрядное целое число со знаком, ее значение может находиться в диапазоне от -32768 до 32767. Если операция с этой переменной дает результат больше 32767 или меньше -32768, произошло целочисленное переполнение. .
Когда происходит целочисленное переполнение, результат операции не определен и может привести к неопределенному поведению в программе:• Зацикливание Результат может привести к зацикливанию значения. Это означает, что число 32768 будет фактически сохранено как 1, так как оно на 1 единицу больше, чем максимальное значение, которое мы можем сохранить (32767).• Усечение Результат может быть усечен или иным образом изменен, чтобы соответствовать диапазону целочисленного типа. Например, число 32768 будет сохранено как 32767, поскольку это максимальное значение, которое мы можем сохранить.
Неопределенное поведение программы — одна из худших ошибок, потому что ее нелегко воспроизвести. Поэтому его трудно отследить и отремонтировать.
Если вы активируете это, придется заплатить небольшую цену: скорость программы немного снизится.
проверка ввода-вывода
Проверяет результат операции ввода-вывода. В случае сбоя операции ввода-вывода возникает исключение. Если этот переключатель выключен, мы должны вручную проверить наличие ошибок ввода-вывода. Если вы активируете это, придется заплатить незначительную цену: скорость программы снизится, но незначительно, потому что несколько микросекунд, введенных этой проверкой, ничто по сравнению с миллисекундным диапазоном времени, требуемым самой операцией ввода-вывода (жесткий диски медленные).
Проверка диапазона
Компьютерщик Delphi называет это «самой важной настройкой Delphi», и я полностью с этим согласен. Он проверяет, находятся ли все выражения индексации массивов и строк в определенных границах. Он также проверяет, чтобы все присвоения скалярным переменным и переменным поддиапазона находились в допустимых пределах.
Вот пример кода, который разрушил бы нашу жизнь, если бы Range Checking был недоступен:
Type
Pasword= array [1..10] of byte; // we define an array of 10 elements
…
x:= Pasword[20]; // Range Checking will prevent the program from accessing element 20 (ERangecheckError exception is raised). Security breach avoided. Error log automatically sent to the programmer. Bruce Willis saves everyone.
Включение проверки ошибок во время выполнения
Чтобы активировать проверку ошибок во время выполнения, перейдите в «Параметры проекта» и установите следующие три флажка:
Включение проверки ошибок во время выполнения в «Параметры проекта»
Утверждения
Хороший программист ДОЛЖЕН использовать утверждения в своем коде для повышения качества и стабильности программы. Серьезно мужик! Вам действительно нужно их использовать.
Утверждения используются для проверки условий, которые всегда должны быть истинными в определенной точке программы, и для возбуждения исключения, если условие не выполняется. Процедура Assert, определенная в модуле SysUtils, обычно используется для выполнения утверждений.
Вы можете думать об утверждениях как о модульном тестировании для бедняков. Я настоятельно рекомендую вам глубже изучить утверждения. Они очень полезны и не требуют такой большой работы, как модульное тестирование.
Типичный пример:
SysUtils.Assert(Input <> Nil, ‘The input should not be nil!’);
Но чтобы программа проверяла наши ассерты, нам нужно активировать эту фичу в Настройки проекта -> Параметры компилятора, иначе они просто будут игнорироваться, как будто их нет в нашем коде. Убедитесь, что вы понимаете последствия того, что я только что сказал! Например, мы сильно облажаемся, если вызываем подпрограммы, имеющие побочные эффекты, в Assert. В приведенном ниже примере во время отладки, когда включены утверждения, будет выполнена функция Test(), и в памятке появится сообщение «Это было выполнено». Однако во время Release more этот текст не будет отображаться в памятке, потому что теперь Assert просто игнорируется. Поздравляем, мы только что изменили поведение программы в режиме отладки/релиза ☹.
function TMainForm.Test: Boolean;
begin
Result:= FALSE;
mmo.Lines.Add('This was executed');
end;
procedure TMainForm.Start;
VAR x: Integer;
begin
x:= 0;
if x= 0
then Assert(Test(), 'nope');
end;
Вот несколько примеров того, как его можно использовать:
1 Чтобы проверить, находится ли входной параметр в диапазоне 0..100:
procedure DoSomething(value: Integer);
begin
Assert((value >= 0) and (value <= 100), 'Value out of range');
…
end;
2 Чтобы проверить, не является ли указатель нулевым, перед его использованием:
Var p: Pointer;
Begin
p := GetPointer;
Assert(Assigned(p), 'Pointer is nil');
…
End;
3 Чтобы проверить, имеет ли переменная определенное значение, прежде чем продолжить:
var i: Integer;
begin
i := GetValue;
Assert(i = 42, 'Incorrect response to “What is the answer to life”!');
…
end;
Утверждения также можно отключить, определив символ NDEBUG в параметрах проекта или используя директивы компилятора {$D-}.
Мы также можем использовать Assert как более элегантный способ обработки ошибок и исключений в некоторых случаях, так как он может быть более читаемым, а также включает собственное сообщение, которое поможет разработчику понять, что пошло не так.
Лично я часто использую его в начале своих подпрограмм, чтобы проверить правильность параметров.
Активация этой функции (естественно) сделает вашу программу медленнее, потому что… ну, есть одна дополнительная строка кода для выполнения.
Ничего не приходит бесплатно
Все хорошее имеет свою цену (в нашем случае, к счастью, небольшую): включение проверки ошибок во время выполнения и утверждений замедляет нашу программу и делает ее несколько больше.
Современные компьютеры имеют много оперативной памяти, поэтому небольшое увеличение размера не имеет значения, так что давайте отложим это в сторону. Но давайте посмотрим на скорость, потому что это не то, что мы можем легко игнорировать:
Type Disabled Enabled
Range checking 73ms 120ms
Overflow checking 580ms 680ms
I/O checking Not tested Not tested
Как мы видим, эти проверки во время выполнения сильно влияют на скорость работы программы. Если у нас есть программа, где критична скорость, лучше активировать «Проверку ошибок во время выполнения» только во время отладки. То, что я делаю, я также оставляю его активным в первом выпуске и жду несколько недель. Если об ошибках не сообщается, то я выпускаю обновление, в котором «Проверка ошибок во время выполнения» отключена.
Лично я оставляю «Проверка ввода-вывода» всегда активной. Падение производительности из-за этой проверки микроскопическое.
Большое предупреждение:
если у вас есть существующий проект, который был написан не очень хорошо, и вы активируете любую из приведенных ниже проверок ошибок выполнения, ваша программа может падать чаще, чем обычно. Нет, процедуры проверки ошибок во время выполнения не нарушали работу вашей программы. Он всегда был сломан – вы просто не знали. Подпрограммы Runtime Checking теперь находят все те места, где код подозрительный, дерьмовый и вонючий. Единственная цель Runtime Checking — найти ошибки в вашей программе.