2016-03-01 46 views
4

編譯器顯示我下面的代碼如下警告:如何擺脫`繼續`困惑的編譯器警告?

Warning: W1036 Variable 'Address' might not have been initialized 

的代碼(MVCE片段基於真正的代碼):

function DoFoo(): Integer; 
var 
    i: Integer; 
    Address, Bar: Cardinal; 
begin 
    for i := 1 to 5 do 
    begin 
    try 
     Address := Hex2CardPos(IntToStr(i)); 
    except on EConvertError do 
     continue; 
    end; 
    Bar := Address + 42; // "Warning: Address might not have been initialized" 
    end; 
    Result := 42; 
end; 

正如你所看到的,Address可以是:

  1. 分配到Hex2CardPos()
  2. 的結果會引發錯誤,並立即跳過循環迭代。

我試圖通過增加一個無用Address := 0;到循環的開始解決這個問題,但隨後的警告只是替換另一個:

Hint: H2077 Value assigned to 'Address' never used. 

這是一個編譯器缺陷或不警告有物質?

+2

'TryHex2CardPos'函數會讓你的生活在這裏變得更輕鬆 –

+0

@DavidHeffernan這個函數在輸入錯誤的情況下會返回什麼,觸發'EConvertError'?讓它引發異常並讓處理程序處理它似乎是最乾淨的。 – DBedrenko

+2

如果您期望常規處理錯誤的輸入數據,那麼通過布爾值指示成功或失敗的版本通常比使用異常的版本更清晰。作爲一個寬泛的規則,如果你想在一個異常處理程序中包裝一個低級別的函數調用,那麼這個函數設計的很糟糕。請參閱'StrToInt'和'TryStrToInt'。 –

回答

8

問題出在您的代碼中。 "Bar"分配必須是在try塊除外,因爲當發生異常你不想分配"Bar"

function DoFoo(): Integer; 
var 
    i: Integer; 
    Address, Bar: Cardinal; 
begin 
    for i := 1 to 5 do 
    begin 
    try 
     Address := Hex2CardPos(IntToStr(i)); 
     Bar := Address + 42; 
    except on EConvertError do 
     continue; 
    end; 
    end; 
    Result := 42; 
end; 

順便說一下這個代碼有一個"H2077 Value assigned to 'Bar' never used"這是正確的。

+0

哈!所以就是這樣。我遵循了一般規則,即儘可能隔離我打算捕獲的異常代碼(即'try'塊中的代碼)。感謝您的回答 – DBedrenko

+3

僅僅因爲您確定了使警告消失的代碼排列並不意味着問題出現在代碼中。編譯器確實是錯誤的;你已經確定了一個*解決方法*。編譯器*應該能夠在原代碼中識別出沒有路徑指向跳過「地址」賦值的「Bar」分配。 –

+1

同意。編譯器在這裏有缺陷。 –