[fpc-pascal] Re: Correct use of var in function calls?

Bo Berglund bo.berglund at gmail.com
Sat Feb 5 09:11:54 CET 2011

On Fri, 4 Feb 2011 19:10:33 +0100, Jonas Maebe
<jonas.maebe at elis.ugent.be> wrote:

>On 04 Feb 2011, at 16:25, Bo Berglund wrote:
>> OK, what will happen if I have a declaration like this:
>> function TSSCommBuf.Read(var Data: TByteArr): boolean; 
>> as opposed to
>> function TSSCommBuf.Read(Data: TByteArr): boolean;
>> Will they be equivalent or will there be an "extra layer" of pointer??
>They are different. And it's not just "an extra layer of pointer", 
>both declarations allow you to do different things. In the second case, 
>you make a copy of the dynamic array and hence its reference count is 
>increased. In the first case, you pass in the original dynamic array in, 
>and hence
>a) no increase in reference count
>b) if you do e.g. "data:=nil", then the variable that was passed in will 
>set to nil and the reference count of the dynamic array will decrease 
>(and if it becomes zeroed, it will be freed)

I made a test in Delphi7 as follows:

  TByteArr = array of byte;

function TForm1.FillArray(Arr: TByteArr): boolean;
  i, Len: integer;
  Len := Length(Arr);
  for i := 0 to Len-1 do
    Arr[i] := i mod 256;

procedure TForm1.Button1Click(Sender: TObject);
  Len: Cardinal;
  i, s1, s2: integer;
  FLocal: TByteArr;
  P1, P2: Pointer;
  Len := speSize.Value;
  SetLength(FBuf, Len);
  SetLength(FLocal, Len);
  s1 := Length(FBuf);

When I reach this position the debugger shows that FLocal contains the
data (0,1,2,3,4,5,6.....) which were entered by the FillArray
function, which seems to contradict your statement that a *copy* of
the array is made for use in the called function.

I then tried two other variations of the same function:

function TForm1.FillArray(var Arr: TByteArr): boolean;

function TForm1.FillArray(const Arr: TByteArr): boolean;

In all these cases the data entered into the array in the FillArray
function remain when the call returns. THe array contains (0,0,0,0...)
before the calls and (0,1,2,3,4,5...) after the calls.

To me it looks like the dynamic array is *always* passed by
*reference* to the FillArray function in Delphi 7....

So is there a difference here between Delphi7 and FPC?

It is difficult to check this in Lazarus since the debugger is not as
functional as in Delphi....

Bo Berglund
Developer in Sweden

More information about the fpc-pascal mailing list