Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler warning "return value might be undefined"

I often use code along the lines of:

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;

Unfortunately the compiler gives me a warning for all these methods:

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

I know this warning, but in this case I can't see any reason for it at all. Or is there a scenario that I am missing that would result in an undefined result value? I understand the warning in the case of try..except but for try..finally it does not make sense to me.

Questions:

  • Is there any reason for the warning?
  • How can I get rid of it (moving the Result := Object.Number line out of the lock is not an option, and I want to avoid writing an completely unnecessary Result := 0 line at the top of each function)

Thanks!

like image 915
jpfollenius Avatar asked Jul 04 '11 10:07

jpfollenius


2 Answers

Is there any reason for the warning?

I can't see one but it is there because of the raise

How can I get rid of it (moving the Result := Object.Name line out of the lock is not an option, and I want to avoid writing an completely unncessary Result := 0 line at the top of each function)

Move the raise statement to a procedure of it's own.

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;
like image 68
Mikael Eriksson Avatar answered Nov 12 '22 19:11

Mikael Eriksson


That is a compiler bug. If the try/finally is removed then the warning is not emitted. The compiler has long been able to recognise that a raise absolves the coder of the obligation to assign the return value. For whatever reason the try/finally appears to confuse its analysis.


On second thoughts perhaps it's not a compiler bug. What if the code in the finally block stopped the exception propagating? Clearly there's not an except handler, but I rather suspect that one of the exception support routines in the System or SysUtils unit may be able to stop the exception progressing further.

like image 32
David Heffernan Avatar answered Nov 12 '22 19:11

David Heffernan