6

次のコードがあるとします。

function DoSomething:Boolean;
var obj : TMyObject;
i : Integer;
begin
  Result := False; //We haven't executed GetValue() correctly yet
  obj := TMyObject.Create();
  try
    //perform some code that may produce an exception        
    i := obj.GetValue();
    //Set the return to True as we executed GetValue() successfully
    Result := True;
  finally
    //do some cleanup
    obj.Free; 
  end;
end;

Delphiコンパイラは、Resultに割り当てられた値が最初の行で使用されないことを訴えています。

私はおそらく明らかな何かを見逃していますが、コンパイラがこれを最適化する理由がわかりません(最適化がオンになっている場合)。

私は常に、変数の値が何であるかを混乱させないように、変数を明示的に設定するように教えられてきました。その上、GetValue()関数が例外を生成した場合、そのResult := True;行は実行されません。したがって、Delphiが変数を初期化したものに翻弄されます。

それで、この安全で許容できるコードですか?メソッドの最初の行を削除するだけで、読みにくくなりますか?これに失敗すると、特定のコンパイラの警告をオフにする必要がありますが、この警告メッセージが有用な情報を提供する可能性があるため、オフにすることには消極的です。

4

2 に答える 2

16

コンパイラは正しいです。結果へのFalseの割り当ては無駄であり、関数が返すことができる唯一の値はTrueです。

可能な2つの実行パスは次のとおりです。

  1. この関数は例外を発生させず、Trueを返します。
  2. この関数は例外を発生させるため、結果値をまったく返しません。

解決策は簡単です。ResultをFalseに設定するコード行を削除してください。この時点で、戻り値は目的を果たさないことが完全に明らかになり、関数をプロシージャに変換するだけで済みます。

于 2012-06-13T06:18:48.067 に答える
5

関数の結果は2つだけです。返さTrueれるか、例外が発生するため、警告を消す代わりにプロシージャに変換できます。

関数の結果を例外が発生したFalseときにしたい場合GetValue()は、その例外をキャプチャしてDoSomething、戻り値をに設定する必要がありますFalse。その場合、戻り値をに初期化して関数を開始する必要がありますTrue

このようなもの:

function DoSomething:Boolean;
var
  obj : TMyObject;
  i: Integer;
begin
  Result := True;
  obj := TMyObject.Create();
  try
    try
      i := obj.GetValue();
    except
      Result := False;
    end;
  finally
    obj.Free;
  end;
end;
于 2012-06-13T05:46:52.543 に答える