A word about ‘out’ parameters in Delphi

Delphi compiler has a contract – any interface variable should be either a valid reference or nil. The same also applies to other lifetime managed types – strings and dynamic arrays. An interesting consequence of the contract is how Delphi interprets ‘out’ function parameters.
As the name suggests, ‘out’ means that an input value of a parameter should be ignored inside a function; but Delphi compiler cannot ignore input value of a lifetime managed instance. It decrements the reference count of an instance when an instance is no longer needed if a reference to instance is not nil.
As a workaround Delphi compiler applies the following trick. Suppose we have a procedure

procedure Foo(out II: IInterface);
  II:= TInterfacedObject.Create;

a call of the procedure


compiles as:

II:= nil;


procedure Bar(var II: IInterface);
  II:= TInterfacedObject.Create;

Bar procedure decrements the reference count of the input parameter instance; the meaning of ‘out‘ parameter forbids to do so. Since Delphi compiler cannot ignore input value of a lifetime manage instance the problem was solved by assigning nil value to a parameter before calling a procedure.


7 thoughts on “A word about ‘out’ parameters in Delphi

    • Documentation is poor as usual. Out counts only for lifetime managed types – otherwise it is an alias for var. At least it is so for Delphi XE.

      • I just wanted to say, I’ve always understood the meaning of “out” as “discards input”, rather than “ignores input”, clearly different from “var”. (I found your interpretation surprising.) You could also look at “ignoring input” as a special case of “discarding input” for non-managed types.

      • Well if you read documentation further you see “The call to GetInfo immediately frees the memory used by MyRecord, before program control passes to the procedure” which is simply untrue. I suppose ‘discard’ means something done with the data, but in this sense the data is ‘discarded’ only for lifetime managed types. For the other types nothing happens with the data passed as ‘out’ parameter, the same as with ‘var’ parameter.

      • While this is true at a compiler level, if the input value is insignificant, it is good style to clear the value to a known zero state yourself, and use the out keyword, so that the intention of the API is clear, even in unmanaged NON-COM objects. If you’re NOT going to explicitly initialize your objects, then maybe it’s a trap to assume that an out value is always going to be set. One should always zero stack-allocated records that are going to be used in var or out cases, to avoid craziness anyways.

  1. Pingback: On the “out” parameter specifier in Delphi | The Programming Works

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s