辞書から要素をポップする関数があります。何か問題が発生した場合は、例外をスローする必要があります。コードはかなり大丈夫に見えます。
type
ENoSuchElementException = class(Exception);
var
FResults: TDictionary<Cardinal, TObject> = TDictionary<Cardinal, TObject>.Create;
FLock: TCriticalSection = TCriticalSection.Create;
/// <exceptions cref="ENoSuchElementException">Element does not exist</exceptions>
function Take(Id: Cardinal): TObject;
begin
FLock.Acquire;
try
try
Result := FResults[Id]; // here may throw exception
FResults.Remove(Id);
except
on E: Exception do
begin
raise ENoSuchElementException.Create(E.ToString);
end;
end;
finally
FLock.Release;
end;
end;
しかし、DelphiXE4コンパイラはについて文句を言いW1035: Return value of function 'Take' might be undefined
ます。
私は突然とても混乱しています。例外がスローされた場合でも、コードが戻り値を期待しているのはなぜですか?それtry...finally
は例外を食べるという意味ですか?誰かが私のコードの問題を指摘できますか?
解決済み: Davidが述べたように、try...except
は外側に移動する必要があります。ありがとう!
これは、32ビットコンパイラによって報告された誤検知のようです。64ビットコンパイラは、コードの警告を報告しません。そして、64ビットコンパイラは正しいです。おそらく、32ビットコンパイラは、例外をキャッチしていることを認識し、その後常に別の例外を発生させることを検出しません。
32ビットコンパイラの誤診を回避する1つの方法は、try / exceptを最も外側のブロックにすることです。次のSSCCEを検討してください。
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure Foo;
begin
end;
function Take1(const Id: Integer): Integer;
begin
try
try
Foo;
Result := 42;
except
on E:Exception do
begin
raise Exception.Create(E.ToString);
end;
end;
finally
end;
end;
function Take2(const Id: Integer): Integer;
begin
try
try
Foo;
Result := 42;
finally
end;
except
on E:Exception do
begin
raise Exception.Create(E.ToString);
end;
end;
end;
begin
end.
コンパイラの出力は次のとおりです。
[dcc32警告] W1035関数「Take1」の戻り値が未定義の可能性があります
だから、Take1
あなたのコードの私の簡略化されたバージョンです。32ビットコンパイラはそのことを警告します。そして、Take2
の順序入れ替えexcept
などをfinally
。そして、コンパイラは警告しません。
おそらく、この回避策はあなたのためのものではありませんが、あなたはこの性質の何かを考え出す必要があります。
肝心なのは、分析が正しく、コンパイラが間違っているということです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加