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 はデフォルトでコードの最適化を実行します。 [プロジェクト] > [オプション] > [コンパイラ]で無効にできます。

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}

最後に、[プロジェクト] > [オプション] > [Diectories/Conditionals] の [Conditional defined] セクションで、「DEBUG」と「NDEBUG」(または古いバージョンの Delphi では同等のもの)が定義されていることを確認します。

于 2015-07-24T14:37:46.533 に答える
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;

--jeroen

于 2010-11-04T10:08:46.560 に答える
0

コンパイラが、このような明らかに死んでいるコードを排除するとは思えません。冗長として排除できたはずのコードにブレークポイントを設定するのに苦労したことはありません。

于 2010-11-03T03:10:02.133 に答える