jpfollenius
jpfollenius

Reputation: 16602

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:

Thanks!

Upvotes: 12

Views: 1623

Answers (3)

David Heffernan
David Heffernan

Reputation: 612794

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.

Upvotes: 3

Mikael Eriksson
Mikael Eriksson

Reputation: 138960

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;

Upvotes: 5

Jiri Kriz
Jiri Kriz

Reputation: 9292

An assignment

Result := ...;

in the finally block is missing.

Upvotes: -2

Related Questions