2012-07-19 88 views
4

我得到一個編譯器警告我不明白:編譯器爲什麼警告該變量可能未被初始化?

procedure Test; 
var 
    Var1: Integer; 
begin 
    while True do 
    begin 
     try 
      if System.Random > 0.5 then 
      begin 
       ShowMessage('Skipping'); 
       continue; // If I remove this line, the warning goes away 
      end; 
      Var1:=6; 
     except on 
      E:Exception do 
      begin 
       ShowMessage('Error'); 
       raise; 
      end; 
     end; 
     ShowMessage(IntToStr(Var1)); // Compiler warning on this line 
    end; 
end; 

當我在2010年德爾福編譯這個我得到:

[DCC警告] OnlineClaimManagerMainU.pas(554):W1036變「VAR1」 可能尚未初始化

如果我刪除調用「繼續」,警告消失。

此外,如果我刪除try/except子句(並保留繼續),警告消失。

如果在沒有初始化Var1的情況下執行到達問題行將如何執行?

+1

編譯器的分析是不深你的。不能確定Var1是否已經初始化。你知道Var1總是被初始化,但編譯器沒有你的分析天賦。 – 2012-07-19 06:12:38

+1

請...我紅着臉:-) – awmross 2012-07-19 06:17:47

+0

所以...爲什麼去掉繼續解決這個問題?同樣的問題將適用。還是僅僅是兩者結合的複雜性讓編譯器頭腦發生了變化? – awmross 2012-07-19 06:21:19

回答

4

Var1將始終在使用前初始化。編譯器會被try - except處理混淆:編碼器的代碼太複雜,無法真正確定Var1總是被初始化。它認爲有可能是Var1:=6;前處理的異常,這會使Var1未初始化的,但它並沒有看到那個例外總是會被重新提出。

+0

它不會,本地未管理的變量不會自動初始化。 – 2012-07-19 06:20:29

+0

@Cesar HVD是指使用 – 2012-07-19 06:21:38

+0

事實上,由於之前總是初始化。 – hvd 2012-07-19 06:34:26

0

您應該但ShowMessage(IntToStr(Var1));進入try除了塊。 那麼它應該是明確的編譯器,這是Var1和intialized看起來更乾淨的代碼。

+1

做這意味着,如果'ShowMessage'導致異常(是的,它可以做到這一點,而且,我假設它是從代碼,並不僅僅是調用'ShowMessage'簡體),異常處理程序將運行,而它不會在問題的代碼中。 – hvd 2012-07-19 08:10:47

0

這是一個非常好的警告。它告訴你不要爲可能在代碼中其他地方使用的變量賦值。警告還會告訴您,如果使用它,那麼分配給它的值可能不是您所期望的。

+1

我想你還沒有明白這個問題。 – 2012-07-19 21:52:29

+0

@羅伯·肯尼迪我想你誤解了我的答案。 Var1的值未在路徑中分配。因此警告。如果您不同意,請爲您的評論添加一些值。 – Rob 2012-07-20 09:11:46

+1

很好。這個問題沒有問到警告的含義。它問爲什麼警告是在這種情況下給出的,特別是因爲看似無關的變化影響警告的外觀。人們很清楚Var1 *是在警告指出的地方分配的,但編譯器沒有看到。你的回答表明你認爲警告是正確的;請說明如何。 – 2012-07-20 12:46:20

相關問題