Re: Delphi procedure declaration var

Posted by John, DelphiLand Team on May 20, 2006

In Reply to Delphi procedure declaration var posted by Johan P14205 on May 18, 2006

: The keyword "var" in the declaration of a Delphi procedure means that I send a "reference" to a
variable, not only the value of the variable. For example:
:
: S := 'abc';
: DoSomething(S); // (1)
: ShowMessage(S); // (2)
:...
: procedure DoSomething (var Param: string);
: begin
: Param := Param + 'def';
: ...
: After calling DoSomething in line (1), S is changed. Line (2) shows 'abcde'.
: But S would stay the same if DoSomething is defined without VAR, such as:
:
: procedure DoSomething (Param: string);
: begin
: Param := Param + 'def';
: ...
: So far, so good. But there seem to be exceptions on this rule: what if I don't use VAR
: and Param is a record, or an object, or an array?
: When is VAR needed?

When using the keyword var in a procedure or function, you pass variables by reference. Such a routine can change the values of the original variables.

Without the keyword VAR, you pass the variable by value. The original variables can NOT be changed by the routine, including records and arrays. There's one exception: when a variable is an OBJECT, it can be changed -- but that's because in fact you are not passing the object itself but a "pointer" to it.

Example 1: passing an array "by reference"

After returning from the call to ProcessArray, A[1] will be '456'

var
  A: array[1..3] of string;
begin
  A[1] := '123';
  ProcessArray(A);
  ShowMessage(A[1]);   // now A[1] is '456' 
  ...

procedure ProcessArray(var Arr: array of string);
var
  i: integer;
begin
  for i := Low(Arr) to High(Arr) do
    Arr[i] := '456';
end;

Example 2: passing an array "by value"

  A[1] := '123';
  ProcessArray2(A);
  ShowMessage(A[1]);   // A[1] is still the same: at '123' 
  ...

procedure ProcessArray2(Arr: array of string);
var
  i: integer;
begin
  for i := Low(Arr) to High(Arr) do
    Arr[i] := '456';
end;

Example 3: passing an object "by value"

This is possible because P doesn't receive the panel component itself, but a pointer to the component:

  Panel1.Color := clYellow;
  ChangeColor(Panel1);
  // Now, the panel will be white
		...
		
procedure ChangeColor(P: TPanel);
begin
  P.Color := clWhite;
end;

Related Articles and Replies