Hi,

perhaps a  safe, generic function for this copying could be added to the RTL. Like:

Procedure ManagedMove<T>(const source: T;var dest: T;count: SizeInt);


a) For non-managed types it would be the same as Move(source, dest, count*sizeof(T))

b) For reference counted types (like strings or interfaces or records of them), it would do:

1. finalize dest
2. normal Move
3. clear source, with fillchar

(for ranges where source and dest overlap, it should skip 1 and 3 for the overlapping elements. Like when you shift some elements in an arrays by two elements to the left, it only has to finalize the two overridden elements before the shifted elements, and clear the last two shifted elements. There is only one way to do that keeps the reference counts valid)

c) For user-defined managed, not reference counted types, it would just do

      for i := 0 to count - 1 do dest[i] := source[i]

Because you really want to use Move for strings, it can be vastly faster than updating the refcounts. But it might not work with user-defined types, like someone could build a managed type that cannot be moved. E.g.:

 type TA = record
  class operator Initialize(var a: TA);
  procedure dosomething;
end;

var globalPointer: ^TA;
class operator TA.Initialize(var a: TA);
begin
  globalPointer := @a;
end;
procedure TA.dosomething;
begin
  assert(globalPointer = @self)
end;




And when you use IsManagedType, it does not distinguish standard strings with such weird managed types.

And perhaps there could be a special attribute to mark which kind of moving is needed, e.g..

  type [moveable] TA = record
  type [referencecounted] TA = record
  type [nonmoveable] TA = record

Bye,
Benito
On 09.01.21 16:28, Bart via fpc-pascal wrote:
Hi,

This may be a silly question.
I use System.Move() to move items in a dynamic array, like
   Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
Where T is the type of the elements in the array.
This seems to work as expected.

I have some questions though:

1. Does this depend on the alignment of the array?
2. Is it OK if the elements of the array are (or contain) managed types?
3. Are there caveats if T is a specialization of a generic type definition?

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

Reply via email to