[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