2016-03-01 6 views
4

Компилятор показывает мне следующее предупреждение для кода ниже:Как избавиться от предупреждения компилятора, запутанного `continue`?

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. Hex2CardPos() выдает ошибку, и итерация цикла немедленно пропускается.

Я попытался это исправить, добавив бесполезный Address := 0; в начале цикла, а затем предупреждение просто заменяется другим:

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

Является ли это ошибка компилятора или делает предупреждение есть вещество?

+2

Функция 'TryHex2CardPos' сделала бы вашу жизнь намного проще здесь –

+0

@DavidHeffernan Что бы эта функция вернулась в случае плохого ввода, который запускает« EConvertError »? Кажется чистым, чтобы он мог вызвать исключение и позволить обработчику справиться с этим. – DBedrenko

+2

Если вы ожидаете регулярно обрабатывать плохие входные данные, то версия, указывающая на успех или неудачу с помощью логического типа, обычно более чистая, чем версия, использующая исключения. Как правило, если вы хотите обернуть один вызов функции низкого уровня в обработчике исключений, эта функция плохо разработана. См. 'StrToInt' и' TryStrToInt'. –

ответ

8

Проблема в вашем коде. "Bar" уступка должна быть в попытке за исключением блока, потому что, когда исключение происходит вы не хотите назначить "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; 

Btw этот код имеет "H2077 Value assigned to 'Bar' never used" это правильно.

+0

Ha! Так оно и есть. Я следовал общему правилу, которое заключается в том, чтобы изолировать как можно больше код, исключение которого я намерен поймать (т. Е. Код в блоке 'try'). Спасибо за ответ – DBedrenko

+3

Просто потому, что вы определили перестановку кода, который заставляет предупреждение уйти, не означает, что проблема была в коде. Компилятор действительно ошибается; вы определили * обходной путь *. Компилятор * должен * иметь возможность распознавать в исходном коде, что нет пути к назначению 'Bar', которое пропускает назначение' Address'. –

+1

Согласовано. Компилятор здесь неисправен. –