[fpc-pascal] Managed record questions

Ryan Joseph ryan at thealchemistguild.com
Thu Mar 8 04:13:41 CET 2018


So in the trunk we have managed records now which is a brilliant addition and long overdue. Some questions these bring up:

1) Given the example below we have a template for a standard ref counted record. Shouldn’t there be some “meta record” type that implements this automatically? I’m thinking about adding this to some types but the idea of recreating this same template every time is daunting and records don’t have inheritance so there’s no way to capture it once.

2) This new feature begs the question why can’t classes be kept on the stack OR the heap now like in c++? There’s countless times I allocate a class on the heap (because you have to) when I could have kept it on the stack and the compiler called some destructor it when it goes out of scope. It’s such a common pattern and a shame to be dynamically allocating/freeing memory every time. C++ really cleans up a lot of memory garbage by making it an option of how your classes are allocated but FPC is stuck in the middle with structs/classes being different enough you need to decide once and commit to that memory management scheme for all uses.

type
  TManagedObject = record
  public
  	v: integer;
  private
  	refCount: integer;
  	procedure Deallocate;
  private
    class operator Initialize(var a: TManagedObject);
    class operator Finalize(var a: TManagedObject);
    class operator AddRef(var a: TManagedObject);
    class operator Copy(constref aSrc: TManagedObject; var aDst: TManagedObject);
  end;

procedure TManagedObject.Deallocate;
begin
	writeln('Deallocate');
end;

class operator TManagedObject.Initialize(var a: TManagedObject);
begin
	a.v := 1;
	a.refCount := 1;
end;

class operator TManagedObject.Finalize(var a: TManagedObject);
begin
	a.refCount -= 1;
	if a.refCount = 0 then
		a.Deallocate;
end;

class operator TManagedObject.AddRef(var a: TManagedObject);
begin
	a.refCount += 1;
end;

class operator TManagedObject.Copy(constref aSrc: TManagedObject; var aDst: TManagedObject);
begin
	aDst := aSrc;
	aDst.refCount += 1;
end;

procedure PassManagedObjects (var obj: TManagedObject); 
begin
	obj.v += 1;
end;

procedure TestManagedObjects; 
var
	obj: TManagedObject;
begin
	PassManagedObjects(obj);
	PassManagedObjects(obj);
	writeln('obj: ', obj.v);
end;


Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list