1

我正在使用 Delphi 7 IDE。Delphi 编译器是否优化代码,就像 C++ 编译器在以下链接中所做的那样?

http://msdn.microsoft.com/en-us/library/aa366877(VS.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缓冲区在超出范围之前不会被读取。密码将保留在应用程序堆栈中,在那里它可以在故障转储中捕获或被恶意应用程序探测。

4

5 回答 5

12

是的,当然 Delphi 执行优化。但是,它不执行该SecureZeroMemory函数旨在规避的优化。在 Delphi 中不需要使用该功能;只需使用普通的旧的ZeroMemory,甚至FillChar. 它们不是宏,它们不会做任何 Delphi 认为是可以优化的未使用的赋值语句的事情。

于 2010-11-03T03:09:13.980 回答
3

Delphi 默认执行代码优化,您可以在Project > Options > Compiler中禁用它。

Delphi 帮助提供了一些关于使用何种优化类型的提示:

$O 指令控制代码优化。在 {$O+} 状态下,编译器会执行许多代码优化,例如将变量放入 CPU 寄存器、消除公共子表达式以及生成归纳变量。

它还指出“编译器不会执行任何“不安全”的优化”,但从某种意义上说,它们不会改变执行路径,而不是从安全的角度来看。

于 2010-11-03T02:38:00.903 回答
1

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 中的等效项)。

于 2015-07-24T14:37:46.533 回答
0

我不相信编译器会消除这样明显的死代码。我从来没有遇到过在代码上设置断点的问题,因为这些代码本来可以作为多余的而被删除。

于 2010-11-03T03:10:02.133 回答
0

对于某些场景,编译器可以检测代码是否不可达并消除代码。

例如,编译器正确地消除了下面代码的“无法访问”部分。
它不会为该行生成代码,因此:

  1. 所以没有蓝色项目符号表示有代码
  2. 放置在该行上的断点将在视觉上标记为“不可到达”

刚刚在 Delphi XE 中测试过,但较旧的 Delphi 版本也有类似的行为。

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.

学习代码级别和喜欢级别的优化器何时(或何时不)启动需要相当长的时间。

例如:当您打开优化时,编译器也会在变量不使用时立即消除它们。
有时,它甚至消除了全局符号。 Danny Thorpe(前 Delphi 编译器工程师和首席科学家)曾经写过一个神奇的方法 Touch来防止这种情况发生。
只需在方法末尾调用此 Touch 方法即可在调试期间欺骗优化器:

procedure Touch(var arg);
begin
end;

——杰伦

于 2010-11-04T10:08:46.560 回答