5
votes

Suppose I have the following code:

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;

The Delphi compiler is complaining that the value assigned to Result is never used in the first line.

I'm probably missing something obvious, but i don't see why the compiler would optimize this out (if optimization's are on).

I have always been taught to explicitly set my variables so as no confusion what their values are. On top of that, should the GetValue() function generate an exception, the Result := True; line will never execute. So we are at the mercy of whatever Delphi initialized the variable to be.

So is this safe/acceptable code? Should i simply remove the first line of the method, which would make it a lot harder to read? Failing that I would have to turn the specific compiler warning off, but I'm reluctant to do that as this warning message can give useful information.

2
About your thoughts on what the compiler does with the Result if you don't initialize it, the answer is nothing. See Is Result variable defined from first line in a function?.LU RD

2 Answers

15
votes

The compiler is correct. The assignment of False to Result is futile and the only value your function can return is True.

The two possible execution paths are:

  1. The function does not raise an exception and returns True.
  2. The function does raise an exception, and therefore does not return a result value at all.

The solution is simple, remove the line of code that sets Result to False. At which point it becomes completely clear that the return value serves no purpose and you can simply turn the function into a procedure.

4
votes

Your function has only two outcomes. Either it returns True or it will raise an exception so you could turn it into a procedure instead to make the warning go away.

If you want the result of the function to be False when GetValue() raises an exception you have to capture that exception in DoSomething and set the return value to False. In that case you should start your function initializing the return value to True.

Something like this:

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;