[fpc-devel] Management operators AddRef and Copy vs Copy

Maciej Izak hnb.code at gmail.com
Sun Apr 10 18:53:46 CEST 2016


2016-04-10 14:45 GMT+02:00 Florian Klämpfl <florian at freepascal.org>:

> I think this is the wrong way:
> - AddRef means only to increase the ref. count of the passed data structure
> - Copy is no deep copy, it means only: copy the current data structure, if
> it references managed
> types, their ref. count is increased but they are not copied
>
> Example with dyn. arrays:
> - AddRef increases the ref. count of the passed array, not its members
> - Copy creates a copy of the array, if the members of the array are
> managed, their ref. count is
> increased
>
> So I would call the operator Copy, in case of custom implemented ref.
> counted records, this would be
> an AddRef operation. For a real copy, a procedure like Clone should be
> declared.
>

Proposed implementation is compatible with internal rtti.inc usage
(FPC_ADDREF and FPC_COPY). In my example I mean dyn array of records and
related usage of operators only in context of items of those array.

Important note:
operator Initialize is called after system int_initialize for required
record fields
operator Finalize is called before system int_finalize for required record
fields
operator AddRef is called after int_addref for required fields
operator Copy is called after fpc_Copy_internal for required fields

note for note:
in current FPC implementation int_initialize = FPC_INITIALIZE, int_finalize
= FPC_FINALIZE, int_addref = FPC_ADDREF, fpc_Copy_internal = FPC_COPY

Let me explain this with complex example:

=== code begin ===
type
  TFoo = record // record with all management operators. Existence of
management operators means that the record became managed
  public
    {... some field definitions ...  }
  private
    class operator Initialize(var aFoo: TFoo);
    class operator Finalize(var aFoo: TFoo);
    class operator AddRef(var aFoo: TFoo);
    class operator Copy(constref aSrc: TFoo; var aDst: TFoo);
  end;

procedure TestValue(Value: TFoo); begin end;
procedure TestVar(var Value: TFoo); begin end;
procedure TestConst(const Value: TFoo); begin end;
procedure TestOut(out Value: TFoo); begin end;
procedure TestConstref(constref Value: TFoo); begin end;

  TFooArray = array of TFoo;

var
  Foos: TFooArray;
  Foos2: TFooArray;
begin
  SetLength(Foos, 5); // call 5x FPC_INITIALIZE and 5x TFoo.Initialize
  SetLength(Foos, 6); // call 1x FPC_INITIALIZE and 1x TFoo.Initialize
  SetLength(Foos, 5); // call 1x FPC_FINALIZE and 1x TFoo.Finalize
  Foos2 := Copy(Foos); // call 5x FPC_ADDREF and 5x TFoo.AddRef
  Foos2[0] := Foos[1]; // call 1x FPC_COPY and 1x TFoo.Copy

  // call 1x FPC_ADDREF and 1x TFoo.AddRef
  TestValue(Foos2[1]);
  // call 1x FPC_FINALIZE and 1x TFoo.Finalize

  // ... none
  TestVar(Foos2[1]);
  // ... none

  // ... none
  TestConst(Foos2[1]);
  // ... none

  // call 1x FPC_FINALIZE and 1x TFoo.Finalize
  // call 1x FPC_INITIALIZE and 1x TFoo.Initialize
  TestOut(Foos2[1]);
  // ... none

  // ... none
  TestConstref(Foos2[1]);
  // ... none

end;  // call 10x FPC_FINALIZE and 10x TFoo.Finalize (for Foos and Foos2)
=== code end ===

As far as I understand your proposal is to use TFoo.Clone instead of
TFoo.Copy and TFoo.Copy instead of TFoo.AddRef. That is correct? IMO a
little confusing from system.pp point of view ;)

-- 
Best regards,
Maciej Izak
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20160410/739a1ac6/attachment.html>


More information about the fpc-devel mailing list