[fpc-pascal] Stack alias for ARC like memory management?

Adrian Veith adrian at veith-system.de
Wed Apr 25 13:14:59 CEST 2018


Am 25.04.2018 um 08:34 schrieb Ryan Joseph:
>
>> On Apr 25, 2018, at 12:59 PM, Sven Barth via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>>
>> No. This would more often than not lead to accidents were users pass such an instance to some outer code (it doesn't even need to the routine with the stack object, but some third party routine that for some reason stores the pointer and is called from that routine) and then will trigger an exception in the best case or hard to debug errors in the worst case. 
> I assume if programmers care enough about performance they’re planning out memory usage by stack vs heap they know not to do that. The pointer is only alive for the duration of the scope. I thought this was a good idea because it explicitly lets you opt in when know you really need it and it’s discreet.
>
> If c++ programmers know not to do that why don’t Pascal programmers? There’s endless ways to screw yourself with memory in general (especially in c++) but we still find a way.

If you know what you are doing, you have exactly the "object" type for
that. You can allocate them on the stack or heap and you can inherit
from them, when you need virtual methods the initialization is a bit
strange (and if you need performance virtual methods are wrong anyway).
The benefit is better performance when needed. The downside is that they
are more unsafe to use than "class" type and you should now what you do.
If I need a cheap (performance wise) "procedure of object" for example,
that can't escape from the scope I use them instead of a class:

type
  TDataArray = array of Integer;
  TFilterData = function(element: Integer): Boolean of object;

function FilterData(const data: array of Integer; filter: TFilterData):
TDataArray;
var
  i, lr, el: Integer;
begin
  Result:= nil;
  lr:= 0;
  for el in data do begin
    if filter(el) then begin
      SetLength(result, lr + 1);
      result[lr]:= el;
      inc(lr);
    end;
  end;
end;

type
  TTestClosure = object
    val: Integer;
    function less(element: Integer): Boolean;
  end;

function TTestClosure.less(element: Integer): Boolean;
begin
  Result:= element < val;
end;

procedure Test;
var
  stack: TTestClosure;
  data: TDataArray;
begin
  stack.val:= 10;
  data:= FilterData([2,4,8,10,12], stack.less);
  assert(Length(data) = 3);
end;                         




More information about the fpc-pascal mailing list