Question

I had code with the basic constructs illustrated by the following:

type
    TDynamicArray = array of double ;

var
    a : TDynamicArray ;

    function Func : TDynamicArray ;

    var
        b : TDynamicArray ;

    begin
    SetLength (B, 3) ;
    b [0] := 0.0 ;
    b [1] := 1.0 ;
    b [2] := 2.0 ;
    Result := b ;   // note 1  -- should use Result := Copy (b, 0, Length (b)) 
    end ;

begin
a := Func ;  // note 2  -- should we (or could we) use a := Copy (Func, 0, Length (Func)) 
end.

It had been working fine until lately when the function started returning empty arrays. I then spot this which enlightens me to the fact that simple assignment isn't correct, I need to use Copy.

Two questions:

  • I realise I need 'Copy' on the line marked Note 1 to assign to the function result. Do I need to use Copy also on the assignment of the function result to array a (line Note 2)?.
  • Why did the compiler allow my construct and what was the compiled code actually doing?

I realise I could try these things and see, but I'm a little spooked by the compiler letting questionable stuff through.

Was it helpful?

Solution

There is no reason to use Copy in either of those assignment statements. Normal assignment works fine. When you allocate b, the reference count of the array is 1. When you assign it to Result, the reference count becomes 2. (Personally, I'd just forego b and operate directly on Result from the start.) When the function returns, b goes out of scope and the reference count becomes 1 again. Finally, when the result is assigned to a, nothing happens because Result was actually an alias for a all along. Ultimately, you're left with one unique array, which should be exactly what you intended.

The compiler allowed your code because your code is fine. The compiler recognizes assignments between arrays just as it does assignments between strings and assignments between interface references, and it generates the right code to adjust the reference counts accordingly.

Using Copy would create an entire copy of the array, but you don't need that. Each time you think you need it, it's in a place where you would have immediately discarded the previous copy anyway. Why make a copy when you already have a perfectly good array ready for any use you want?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top