1

我正在使用Delphi 7 IDE。 Delphi編譯器是否優化了代碼,就像C++編譯器在這個鏈接中所做的一樣?Delphi編譯器是否執行優化?

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緩衝區不是從它超出範圍之前閱讀。密碼將保留在應用程序堆棧中,以便在崩潰轉儲中捕獲密碼或由惡意應用程序進行探測。

回答

12

是的,當然德爾福執行優化。但是,它並不執行SecureZeroMemory函數旨在規避的優化。在Delphi中不需要使用該函數;只是使用普通的舊ZeroMemory,甚至FillChar。它們不是宏,並且它們不會執行任何Delphi認爲是可以優化的未使用的賦值語句。

2

德爾福默認執行代碼優化,您可以在項目>選項>編譯器中禁用它。

Delphi幫助提供什麼類型的優化的一些技巧使用:

的$Ø指令控制代碼優化。在{$ O +}狀態下,編譯器執行一些代碼優化,比如將變量放在CPU寄存器中,消除常見的子表達式並生成歸納變量。

它還指出「編譯器不執行‘不安全’優化」,但在某種意義上說,他們不會改變執行路徑,而不是從安全角度考慮。

0

我不相信編譯器會永遠消除這樣的死代碼。我從來沒有麻煩設置可能已被淘汰爲冗餘的代碼斷點。

+7

其實我有。完全不被調用的方法不會被包含在你的.EXE中,而你放在那裏的斷點將不會顯示爲可用。 – 2010-11-03 04:10:13

+0

這種情況不同,@Jeroen。 Loren正在談論* *可達的代碼,但如果它被執行則不會有任何效果。充足的智能編譯器可以認識到代碼沒有任何作用並且可以忽略它。一個很好的例子就是問題中的問題,在清除密碼數組之後永遠不會使用密碼數組。如果編譯器知道把'ZeroMemory'作爲賦值語句,並且它被設置爲優化以後從不使用的賦值,那麼調用'ZeroMemory'可能會被消除。 'SecureZeroMemory'只是一個編譯器不知道可以省略的新函數。 – 2010-11-03 13:20:17

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. 

這需要相當長的一段時間來學習的時候(或者不)在代碼級別和類似器級別踢優化

例如:當你已經優化開啓時,編譯器也將消除一旦不使用它們,就立即變量。
有時甚至會消除全局符號。(前德爾福編譯器工程師兼首席科學家)曾經寫過一個magic method Touch,以防止這種情況發生。
只需撥打你的方法來欺騙優化結束這種觸摸方法在調試過程:

procedure Touch(var arg); 
begin 
end; 

--jeroen

0

德爾福無疑優化了代碼(這是一個現代的,和優秀的,編譯器)。優化刪除線又如:

SomeFunction(); // Set breakpoint here, then step (F10) 
myInt := 7;  // Next line will not hit this... 
myInt := 13;  // ...but will instead skip to here 

我想,以確保優化是正確的狀態(而不是不小心留下開啓或關閉)在我的項目中每一個的.pas文件中添加{$I MyProjectOptions.inc}。這就在單位名稱下方(位於文件頂部)。在「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)定義項目的部分>選項> Diectories/Conditionals。