4

I always was thinking that OleVariant variables always has initial value equal to Unassigned (type VT_EMPTY). But the following simple code compiled with XE3 shows me it is not true.

{$APPTYPE CONSOLE}

uses
  ActiveX;

function GetValue: OleVariant;
begin
  Result := TVariantArg(Result).vt;
end;

function GetValue2: OleVariant;
begin
  Result := 10;
  Result := GetValue;
end;

var
  Msg: string;
begin
  Msg := GetValue2;
  Writeln(Msg);
end.

App writes "3". Is it normal?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Denis Anisimov
  • 3,297
  • 1
  • 10
  • 18
  • A function Result variable has no guaranteed default value. See http://stackoverflow.com/q/10084043/576719. – LU RD Feb 02 '16 at 18:40

1 Answers1

7

The return value of a Delphi function, for types that don't fit in a register, are passed as var parameters. So the compiler transforms the code to be like so:

procedure GetValue(var Result: OleVariant);

Hence the value of Result on entry to the function is the value of the variable that you assign the return value to.

So your calling code is transformed to

function GetValue2: OleVariant;
begin
  Result := 10;
  GetValue(Result);
end;

So in its entirety your program becomes

{$APPTYPE CONSOLE}

uses
  ActiveX;

procedure GetValue(var Result: OleVariant);
begin
  Result := TVariantArg(Result).vt;
end;

procedure GetValue2(var Result: OleVariant);
begin
  Result := 10;
  GetValue(Result);
end;

var
  tmp: OleVariant;
  Msg: string;
begin
  GetValue2(tmp);
  Msg := tmp;
  Writeln(Msg);
end.

Which explains the output of VT_I4.

Of course this is all a consequence of implementation detail. You should always initialize function return values.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 4
    It is a shame that the compiler doesn't always treat the implicit output parameter as an `out` instead of a `var`. – Remy Lebeau Feb 03 '16 at 00:25