[fpc-pascal] Working with anonymous functions

Thomas Kurz fpc.2021 at t-net.ruhr
Fri Mar 10 17:34:14 CET 2023


Dear all,

I'm testing FPC-trunk and I'm especially interested in using anonymous functions because they should simplify working with TThread.Synchronize and others a lot.

I stumbled upon an issue which I'd like to post here first because I am not sure whether it's a bug or just a wrong usage on my side.

Here's a small example:


program project1;

{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}

uses Classes, EventLog, SysUtils;

type
  TTest = class
    FOnLog: TLogMessageEvent;
    procedure CallOnLog (AEventType: TEventType; AMessage: String);
  end;

procedure TTest.CallOnLog (AEventType: TEventType; AMessage: String);

var
  r: reference to TThreadMethod = nil;
  m: TThreadMethod = nil;

begin
  // This doesn't work because the anonymous procedure is
  // capturing local symbols. I understand that this doesn't work.
  m := procedure
    begin
      FOnLog (Self, AEventType, AMessage);
    end;

  // As far as I have understood
  // https://forum.lazarus.freepascal.org/index.php/topic,59468.0.html
  // the solution should be to use a "reference to".
  // In fact, assignment works as expected:
  r := procedure
    begin
      FOnLog (Self, AEventType, AMessage);
    end;

  // But I seem not to have any change to pass the reference.
  // Both versions fail:
  TThread.ForceQueue (NIL, r());
  TThread.ForceQueue (NIL, @r);
end;

begin
end.


As you can see, the goal is to call TThread.ForceQueue. Of course, the easiest solution was having an overloaded "TThread.ForceQueue (TThread, TThreadProcedure)" as is the case with Delphi. I have already posted a feature request on Github.

But I don't know why I can't use a "reference to TThreadMethod". If I understand the feature announcement correctly, this should work, shouldn't it?

Kind regards,
Thomas



More information about the fpc-pascal mailing list