Подтвердить что ты не робот

Предупреждение компилятора "возвращаемое значение может быть undefined"

Я часто использую код по строкам:

function GetNumber(Handle : THandle) : Integer;
begin
FLock.BeginRead;
try
  if FMap.TryGetValue(Handle, Object) then
    raise EArgumentException.Create('Invalid handle');
  Result := Object.Number;
finally
  FLock.EndRead;
end;
end;

К сожалению, компилятор дает мне предупреждение для всех этих методов:

[DCC Warning] Unit.pas(1012): W1035 Return value of function 'GetNumber' might be undefined

Я знаю это предупреждение, но в этом случае я не вижу никакой причины для этого. Или есть сценарий, который мне не хватает, что приведет к значению результата undefined? Я понимаю предупреждение в случае try..except, но для try..finally это не имеет смысла для меня.

Вопросы:

  • Есть ли причина для предупреждения?
  • Как я могу избавиться от него (перемещение строки Result := Object.Number из блокировки не является опцией, и я хочу избежать написания совершенно ненужной строки Result := 0 в верхней части каждой функции)

Спасибо!

4b9b3361

Ответ 1

Есть ли причина для предупреждения?

Я не вижу его, но он существует из-за raise

Как я могу избавиться от него (перемещение строки результата: = Object.Name из блокировка не вариант, и я хочу во избежание полного написания noncessary Результат: = 0 строка вверху каждой функции)

Переместите оператор raise в его собственную процедуру.

function GetNumber(Handle : THandle) : Integer;
    procedure InvHandle;
    begin
        raise EArgumentException.Create('Invalid handle');
    end;
begin
    FLock.BeginRead;
    try
        if FMap.TryGetValue(Handle, Object) then
            InvHandle;
        Result := Object.Number;
    finally
        FLock.EndRead;
    end;
end;

Ответ 2

Это ошибка компилятора. Если элемент try/finally удален, предупреждение не выдается. Компилятор уже давно понял, что a raise освобождает кодера от обязанности присвоить возвращаемое значение. По какой-то причине try/finally, похоже, путает его анализ.


Во-вторых, возможно, это не ошибка компилятора. Что делать, если код в блоке finally остановил распространение исключения? Очевидно, что нет обработчика except, но я скорее подозреваю, что одна из процедур поддержки исключений в модуле System или SysUtils может остановить дальнейшее развитие исключения.

Ответ 3

Назначение

Result := ...;

в блоке finally отсутствует.