Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between "array of double" and TDoubleDynArray

Tags:

delphi

The System.Types unit declares an array type:

TDoubleDynArray  = array of Double;

If I declare a method as:

procedure func (x : TDoubleDynArray)

I notice that the argument x acts like a var argument, ie I can change x inside the method and I'll see the changes reflected outside the method.

However when I use

procedure func (x : array of double)

As expected, any changes in x stays in func. Although TDoubleDynArray appears to be declared as an array of double, it behaves differently from my own array of double. What is the explanation for this?

Update: I noticed that if I declare my own type TMyArray = array of double then I get the same behavior as TDynamicDynArray. Is this something to do with a difference between basic array types?

Test code follows

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.Types;

var
   x : TDoubleDynArray;
   y : array of double;

procedure func1 (x : TDoubleDynArray);
begin
  x[0] := -999.123;
end;

procedure func2 (y : array of double);
begin
  y[0] := -999.123;
end;

begin
    setLength (x, 10);
    func1 (x);
    writeln ('TDoubleDynArray: ', x[0]);

    setLength (y, 10);
    y[0] := 0;
    func2 (y);
    writeln ('array of double: ', y[0]);

    Readln;
end.
like image 413
rhody Avatar asked Mar 15 '23 18:03

rhody


1 Answers

procedure func1 (x : TDoubleDynArray);

The function argument is a dynamic array. That is a reference type. That means that the function argument x is a reference to the array. A consequence of that is that changes to the elements of the array inside func1 change the caller's array.

procedure func2 (y : array of double);

The function argument is an open array parameter. Although it overloads the array of syntax it is quite a different beast from a dynamic array. Because this open array is passed by value, a copy of the array is passed to the function, and so modifications made by the function are not visible to the caller.

It's worth pointing out that, because you passed y by value, a copy of the array is passed. That is inefficient, more so for larger arrays. As a rule, by value open arrays should be avoided. Use either var or a const open array parameters. The same advice applies to other large types, like fixed length arrays and records.

Open array parameters are an endless source of confusion. I recommend that you read the documentation that I linked to, and Rudy's article on the subject: Open array parameters and array of const.

like image 133
David Heffernan Avatar answered Mar 24 '23 12:03

David Heffernan