user1175743
user1175743

Reputation:

Different ways of declaring parameters in procedures and functions

I've noticed that different codes declare parameters in a different way to how I do, and I wonder if there is a specific reason to do so, or whether it is a preference.

Say I wrote this function (just an example with different parameters)

function DoSomething(AHeight, AWidth: Integer; R: TRect): Boolean
begin
  //
end;

How is this any different then if it was declared like so:

function DoSomething(var AHeight, AWidth: Integer; const R: TRect): Boolean
begin
  //
end;

I know a variable is read/writeable and a constant is read-only, but how does declaring parameters this way make a difference?

To me both functions are looking for the calling code to provide a Height, Width and Rect, but the 2nd function makes it look like we are declaring new variables.

I have a feeling this is going to be such a straight forward answer I feel silly for asking but I must know what the difference is, if any?

Upvotes: 2

Views: 2345

Answers (3)

Toon Krijthe
Toon Krijthe

Reputation: 53366

A parameter can be var, const, out and 'none'

Normally, a parameter can be changed by the function, but it does not change the calling parameter.

var
  x,y : Integer;
procedure Text(a: Integer);
begin
  x := a;
  a := 1;
end;
begin
  x := 10;
  y := 20;
  Test(y);
  // x = 20; y = 20;
end.

With a var parameter, the change affects the calling parameter.

var
  x,y : Integer;
procedure Text(var a: Integer);
begin
  x := a;
  a := 1;
end;
begin
  x := 10;
  y := 20;
  Test(y);
  // x = 20; y = 1;
end.

A const parameter, can't be changed.

var
  x,y : Integer;
procedure Text(const a: Integer);
begin
  x := a;
  a := 1; // ERROR!
end;
begin
  x := 10;
  y := 20;
  Test(y);
  // Does not compile
end.

An out parameter is only written.

var
  x,y : Integer;
procedure Text(out a: Integer);
begin
  x := a;
  a := 1;
end;
begin
  x := 10;
  y := 20;
  Test(y);
  // x = undefine y = 1;
end.

Upvotes: 1

SWeko
SWeko

Reputation: 30892

There is a nice discussion of the issue here, but basically, without the var, the parameters is passed by value, and with the var, the parameter is passed by reference.

When a parameter is passed by value copy of the parameter is made, and that copy is given to the function. Any changes to the copy will not be propagated to the original which is separate.

When a parameter is passed by reference, the function is given a reference to the original, so any changes to the copy will be visible even after the call is made.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 612954

The documentation explains this very clearly:

Most parameters are either value parameters (the default) or variable (var) parameters. Value parameters are passed by value, while variable parameters are passed by reference. To see what this means, consider the following functions:

function DoubleByValue(X: Integer): Integer;   // X is a value parameter
begin
  X := X * 2;
  Result := X;
end;

function DoubleByRef(var X: Integer): Integer;  // X is a variable parameter
begin
  X := X * 2;
  Result := X;
end;

These functions return the same result, but only the second one - DoubleByRef can change the value of a variable passed to it. Suppose we call the functions like this:

var
  I, J, V, W: Integer;
begin
  I := 4;
  V := 4;
  J := DoubleByValue(I);   // J = 8, I = 4
  W := DoubleByRef(V);     // W = 8, V = 8
end;

After this code executes, the variable I, which was passed to DoubleByValue, has the same value we initially assigned to it. But the variable V, which was passed to DoubleByRef, has a different value.

A value parameter acts like a local variable that 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.

A variable parameter, on the other hand, acts like a pointer rather than a copy. Changes made to the parameter within the body of a function or procedure persist after program execution returns to the caller and the parameter name itself has gone out of scope.

Even if the same variable is passed in two or more var parameters, no copies are made. This is illustrated in the following example:

procedure AddOne(var X, Y: Integer);
begin
  X := X + 1;
  Y := Y + 1;
end;

var I: Integer;
begin
  I := 1;
  AddOne(I, I);
end;

After this code executes, the value of I is 3.


I recommend that you add a link to the Delphi Language guide to your browser's bookmarks.

Upvotes: 4

Related Questions