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

michael.vancanneyt at wisa.be michael.vancanneyt at wisa.be
Sat Feb 5 09:24:44 CET 2011



On Sat, 5 Feb 2011, Bo Berglund wrote:

> 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:
>
> type
>  TByteArr = array of byte;
> ...
>
> function TForm1.FillArray(Arr: TByteArr): boolean;
> var
>  i, Len: integer;
> begin
>  Len := Length(Arr);
>  for i := 0 to Len-1 do
>    Arr[i] := i mod 256;
> end;
>
> procedure TForm1.Button1Click(Sender: TObject);
> var
>  Len: Cardinal;
>  i, s1, s2: integer;
>  FLocal: TByteArr;
>  P1, P2: Pointer;
> begin
>  Len := speSize.Value;
>  SetLength(FBuf, Len);
>  SetLength(FLocal, Len);
>  FillArray(FLocal);
>  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....

No. Someone misunderstands the concept of dynamic array here.

A "dynamic array" is a pointer to an array in memory.
So when passing a dynamic array to a function, 
you are, in fact, passing a pointer.

> So is there a difference here between Delphi7 and FPC?

No.

Test the following program:

Var
   A,B : Array of byte;
   I : integer;

begin
   SetLength(A,10);
   For I:=0 to 9 do
     A[I]:=I+1;
   B:=A; // A pointer is copied.
   B[5]:=33;
   Writeln(A[5]);
end.

This will write 33.

All this is explained in the Delphi (and FPC) documentation.

Michael.



More information about the fpc-pascal mailing list