Thursday, April 13, 2006

Why doesn't a variable change when assigned a function result?

Consider this:
function someIntFunction: integer;
begin
  if false then
    result := 20;
end;

procedure someIntMethod;
var
  lValue: integer;
begin
  lValue := 10;
  lValue := someIntFunction;
  ShowMessage(IntToStr(lValue));
end;
What does ShowMessage show?

When this code is compiled, a compiler warning is issued for someIntFunction indicating that the result may be undefined. This is a valid warning and what is displayed will be whatever happens to be on the stack; some random value.

Now consider this:

function someStringFunction: string;
begin
  if false then
    result := '20';
end;

procedure someStringMethod;
var
  lValue: string;
begin
  lValue := '10';
  lValue := someStringFunction;
  ShowMessage(lValue);
end;
When this is compiled, there is no warning for someStringFunction. A warning should probably also be emitted, but it's not. The effect however is a bit different. In this case, the variable that the result is assigned to is unchanged. This seems to occur for any type that is reference counted: strings, dynamic arrays and interfaces.