Выполняет ли компилятор Delphi оптимизацию?
-
28-09-2019 - |
Вопрос
Я использую среду разработки Delphi 7 IDE.Оптимизирует ли компилятор Delphi коды точно так же, как это делает компилятор C ++ по этой следующей ссылке?
http://msdn.microsoft.com/en-us/library/aa366877 (ПРОТИВ 85).aspx
WCHAR szPassword[MAX_PATH];
// Retrieve the password
if (GetPasswordFromUser(szPassword, MAX_PATH))
UsePassword(szPassword);
// Clear the password from memory
SecureZeroMemory(szPassword, sizeof(szPassword));
Если ZeroMemory
были вызваны в этом примере вместо SecureZeroMemory
, компилятор мог бы оптимизировать вызов , потому что szPassword
буфер не считывается до того, как он выйдет за пределы области видимости.Пароль останется в стеке приложений, где он может быть захвачен в аварийном дампе или проверен вредоносным приложением.
Решение
Да, конечно, Delphi выполняет оптимизацию. Однако он не выполняет оптимизацию, что SecureZeroMemory
Функция предназначена для обохождения. Нет необходимости использовать эту функцию в Delphi; просто используйте простые старые ZeroMemory
, или даже FillChar
. Отказ Они не макрос, и они не делают ничего, что Delphi распознает как неиспользуемые заявления о назначении, которые могут быть оптимизированы.
Другие советы
Delphi выполняет оптимизацию кода по умолчанию, вы можете отключить его в Проект> Опции> Компилятор.
Helphi Help предоставляет несколько советов о том, какой тип оптимизации используются:
Оптимизация кода управления директивой в $ o. В состоянии {$ O +} компилятор выполняет ряд оптимизаций кода, таких как размещение переменных в регистрах CPU, устраняя общие под воздействия и генерирующие переменные индукции.
Это также утверждает, что «Компилятор не выполняет« небезопасные »оптимизации», но в том смысле, что они не изменит путь исполнения, а не с точки зрения безопасности.
Я не верю, что компилятор когда-либо устраняет, по-видимому, повторному мертвему коду. У меня никогда не было проблем с настройками точки останова в коде, которое могло быть исключено в качестве избыточности.
Для некоторых сценариев компилятор может обнаружить, будет ли код недоступен и устранить код.
Например, компилятор правильно устраняет «недостижимую» часть кода ниже.
Это не будет генерировать код для этой линии, так что:
- Так что нет синих пуль, указывающих, что есть код
- Точки останова, положенные на эту строку, будут ознаменоваться визуально как «не достижимы»
Просто проверено в Delphi Xe, но более старые Delphi Versions имеют подобное поведение.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure Test;
begin
if (True = False) then
Writeln('Unreachable')
else
Writeln('Reachable');
end;
begin
try
Test();
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Требуется довольно какое-то время, чтобы узнать, когда (или когда нет) оптимизатор на уровне кода и уровнем проката.
Например: если у вас включены оптимизации, компилятор также устраняет переменные, как только они не используются.
Иногда он даже устраняет глобальные символы.Дэнни Торп (бывший инженер-компилятор Delphi и главный ученый) после написания Магический метод Touch. Это мешает этому.
Просто нажмите этот метод касания в конце вашего метода, чтобы обмануть оптимизатор во время отладки:
procedure Touch(var arg);
begin
end;
- jereen.
Delphi, безусловно, оптимизирует код (это современный и превосходный компилятор).Другим примером оптимизации удаления строк является:
SomeFunction(); // Set breakpoint here, then step (F10)
myInt := 7; // Next line will not hit this...
myInt := 13; // ...but will instead skip to here
Я хотел бы убедиться, что оптимизация находится в правильном состоянии (а не случайно оставлена включенной или выключенной), добавив {$I MyProjectOptions.inc}
в каждом файле .pas в моем проекте.Это указано чуть ниже названия устройства (в самом верху файла).В "MyProjectOptions.inc" вы просто добавляете этот код:
// Is this a debug or non-debug build?
{$IF Defined(DEBUG)}
{$O-} // Turn optimization off
{$ELSEIF Defined(NDEBUG)}
{$O+} // Ensure optimisation is on
{$IFEND}
Наконец, убедитесь, что вы определили "DEBUG" и "NDEBUG" (или ваш эквивалент в старых версиях Delphi) в разделе "Условные определения" проекта > "Параметры" > "Конструкторы / условные обозначения".