Get "out"! Delphi parameter types

When passing parameters to a procedure or function in Delphi, there are a number of ways to choose between, as in the procedure list below:

procedure Action(ActionRequest : TMyActionRequest); procedure Action(var ActionRequest : TMyActionRequest); procedure Action(const ActionRequest : TMyActionRequest); procedure Action(out ActionRequest : TMyActionRequest);

If you are just a bit experienced working with Object Pascal, you probably already have a good understanding about the differences between the parameter types. But to summarize:

The first type in the list: value parameter, passes the value of the parameter. The called routine is free to read and write the parameter. But the original value is not changed at the caller site.

It also acts like a local variable. It gets initialized to the value passed in the procedure or function call. If you pass a variable as a value parameter, the procedure or function creates a copy of it; changes made to the copy have no effect on the original variable and are lost when program execution returns to the caller. Note though, that when passing an object reference, the called procedure will not be able to change the object itself (its address), but modifying its properties is allowed.

A variable parameter (“var”), on the other hand, acts like a pointer rather than a copy, because the parameter is passed by reference. Changes made to the parameter within the body of a function or procedure, are returned to the caller.

A constant parameter (“const”), is like a local constant or read-only variable. Constant parameters are similar to value parameters, except that you can't assign a value to a constant parameter within the called procedure or function. Also, you cannot pass one as a “var” parameter to another routine. Use this when the parameter is only going to be read. Especially you should use “const” for types like strings, records, interfaces etc., because it gives better performance.

The out parameter (“out”) was introduced back in Delphi 3, together with interfaces. It is also used when the parameter will be changed by the called procedure.

The difference, compared with “var”, is that the called procedure or function does not expect the parameter to contain any initial value. The called procedure cannot rely on the parameter having an initial value. It is only used for passing back a value, like a placeholder. Also, for reference-counted types (strings interfaces etc.), the compiler enforces this by first clearing the variable before passing it to the procedure or function.

However, it seems the compiler does not make any difference between “out” and “var”. The same assembler code is generated for the called procedure, at least in Delphi XE7. This may of course change in a future version, but for now there are not any performance gains.

So, using “out” instead of “var”, gives you a major benefit:

It makes the intent of your code clearer.

As a developer you will know that the called procedure or function does not expect the parameter to contain any initial value. Consequently, it does not make sense for the called procedure or function to read the value and use it. At least not before it has been set.

And indeed, Pascal Analyzer (standalone), and Pascal Expert (IDE plugin) has a couple of new report sections dealing with “out”:

Warnings Report: Out parameter read before set (WARN51)

Optimization Report: Parameter is “var”, can be changed to “out” (OPTI8)

Also, there are a few report sections reporting parameters that should be passed by “const”. Those are in the Optimization Report.