2

I have a variable in a procedure that I need to keep alive until an anonymous method in that procedure runs, but I don't use the variable in the anonymous method. Is there an idiomatic way to tell the compiler to capture the variable anyway?

For example:

procedure ForceCapture(const AVar);
begin
  // No-op
end;

procedure TMyClass.MyProcedure;
var
  Rec: TSearchRec;
begin
  CallAnonMethod(@Rec,
    procedure(retVal: Integer);
    begin
      ForceCapture(Rec); // What should this be?
      if retVal = 0 then ...
    end;
end;

The above works on Win32, but I'm worried that the LLVM backend or some future optimization will recognize that ForceCapture doesn't do anything and remove the capture as a no-op. In this instance, CallAnonMethod must take a pointer, not a reference, so making a copy within it isn't an option.

Zoë Peterson
  • 13,094
  • 2
  • 44
  • 64
  • There's no way you can guarantee that things won't change in the future, don't think you can do better than this. – David Heffernan Oct 03 '18 at 21:31
  • In other way, it's seam that embarcadero will remove the ARC from it's futur compiler, so you will not have anymore to worry about it – zeus Oct 04 '18 at 05:30
  • 3
    @loki Question asked has absolutely nothing to do with ARC. – Dalija Prasnikar Oct 04 '18 at 12:42
  • @DalijaPrasnikar what the purpose to keep something alive else ? – zeus Oct 04 '18 at 13:20
  • 2
    @loki First of all ARC is the thing that keeps things alive as long as necessary. So if someone needs to keep things alive, you can bet they don't talk about ARC. If you read carefully you will see that anonymous method takes a pointer to a TSearchRec - which is record not an object, since it is created on stack it will be dead as soon as MyProcedure finishes. Obviously anonymous method in the question lives longer than that and needs to capture that variable - keep it alive. No ARC in sight - unless you count ARC behind anonymous method that exists in all compilers. – Dalija Prasnikar Oct 04 '18 at 13:35
  • @loki This is about the classic (Win32) compiler, so ARC isn't a concern. Check out the documentation on Anonymous Methods covering "Variable Binding": http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html – Zoë Peterson Oct 04 '18 at 13:41
  • 1
    @Dalija - Pardon my ignorance, how is it possible for the anonymous procedure to outlive MyProcedure? Does it run asynchronously? Otherwise, AFAICS, CallAnonProc will not return until it executes the anonymous procedure. – Sertac Akyuz Oct 04 '18 at 13:56
  • 1
    @SertacAkyuz If it cannot outlive MyProcedure then there would be no problem to solve in the first place. Point is that it could outlive MyProcedure, it is just that part of the code that can keep it alive is not presented in the question. – Dalija Prasnikar Oct 04 '18 at 14:07
  • ... an that part of code is also unnecessary. Question and the problem are clear enough. – Dalija Prasnikar Oct 04 '18 at 14:28

1 Answers1

0

I have resorted to doing something like this in 1 of my Android apps. (Delphi 10.2.3)

procedure TMyClass.MyProcedure;
var
  Rec: TSearchRec;
begin
  CallAnonMethod(@Rec,
    procedure(retVal: Integer);
    var
      LocalRec: TSearchRec;
    begin
      LocalRec := Rec; // yes, it actually works
      if retVal = 0 then ...
    end;
end;
Freddie Bell
  • 2,186
  • 24
  • 43