On 09.01.2021 19:23, Bart via fpc-pascal wrote:
On Sat, Jan 9, 2021 at 5:12 PM Yuriy Sydorov via fpc-pascal
<fpc-pascal@lists.freepascal.org> wrote:

2. Is it OK if the elements of the array are (or contain) managed types?

You need to manually finalize/free elements which are overwritten before 
calling Move.
So, if I move Arr[3] to Arr[1], I first have to finilize/free Arr[1].
After that move the bytes in Arr[3] are exactly the same as in Arr[1]
(by definition of how move works) AFAIU.
Is that a problem with refcounts, because they would be the same also
but the number of copies increased?

System.Move just copies bytes in the memory. So all handling of managed types 
must be done manually.
So if Arr[1] contains a managed value you need to finalize/free it before Move.
After move Arr[1] and Arr[3] will contain the same value and if you need to keep both you need to increase the refcount manually.

Also if you intend to use Move for duplication of elements of managed types, it 
is better to use for-loop to copy each
element separately to allow proper increments of references.

3. Are there caveats if T is a specialization of a generic type definition?


Thanks for explaning.
OK, since this is a generic class, Systme.Move() can be safe, but it
is not guaranteed (almost by definition you never know what <T> is
going to be in the specialization.

If your array contains class object instances and no other references to them exist then you need to Free them before overwriting by Move.

So, I'll use a for loop to copy the data.

I assume that doing Arr[Index] := Default(T) will also finalize the
element if that element ismanaged?

For class object instances call Arr[Index].Free, for other managed types or records containing managed types Finalize(Arr[Index]) should work.

Yuriy.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to