Skip to content
GitLab
    • GitLab: the DevOps platform
    • Explore GitLab
    • Install GitLab
    • How GitLab compares
    • Get started
    • GitLab docs
    • GitLab Learn
  • Pricing
  • Talk to an expert
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
    Projects Groups Snippets
  • Sign up now
  • Login
  • Sign in / Register
  • FPC Source FPC Source
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Graph
    • Compare
    • Locked Files
  • Issues 1,357
    • Issues 1,357
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 73
    • Merge requests 73
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FPC
  • FPCFPC
  • FPC SourceFPC Source
  • Issues
  • #39926
Closed
Open
Issue created Sep 29, 2022 by bogen85@bogen85

Want direct capture of nested procedure/function into a reference to procedure/function to work (for anonymous procedures/functions)

Summary

  • Indirect capture of a nested procedure works, direct capture does not always work.
  • Would like equal capture of everything in the parent/containing scope.

System Information

  • Operating system: Linux, FreeBSD (but should work for All)
  • Processor architecture: x86-64, AARCH64 (but should work on All)
  • Device: Computer (but should work on all)

Example Project

This does not work, a direct capture of nested procedure.

{$mode delphi}
{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}

program nocapture;

type
  tSimpleProc = reference to procedure;

procedure main;

  var
    tcf: tSimpleProc;
    x: integer;

  procedure nested;
    begin
      writeln ('Hello from nested! x: ', x);
      inc(x);
    end;

  begin
    x := 100;

    tcf := procedure begin nested; end;
    tcf();
    tcf();

  end;

begin
  main;
end.

The above results in:

Free Pascal Compiler version 3.3.1 [2022/09/26] for x86_64
Copyright (c) 1993-2022 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling src/nocapture.pas
nocapture.pas(25,28) Error: Symbol "nested" can not be captured
nocapture.pas(34) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /home/shared-development/fpc_usr/lib/fpc/3.3.1/ppcx64 returned an error exitcode

This does work, example includes indirect capture to get the nested procedure to be captured.

{$mode delphi}
{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}

program doescapture;

type
  tSimpleProc = reference to procedure(const n: integer);

procedure main0;

  var
    tcf: tSimpleProc;
    tcf2: tSimpleProc;
    x: integer;

  procedure nested(const n: integer);
    begin
      writeln ('Hello from nested! ', n, ' x: ', x);
      inc(x);
    end;

  begin
    tcf := nested;
    x := 100;

    procedure(const aArg: String) begin Writeln(aArg); end('Hello World');
    procedure begin nested(1); end();
    tcf2 := procedure(const n: integer) begin tcf(n); end;
    tcf2(2);
  end;


procedure main1;
  var
    x: integer;

  begin
    x := 132;
    procedure begin writeln ('x = ', x) end();
  end;

begin
  main0;
  main1;
end.

Produces this output:

Hello World
Hello from nested! 1 x: 100
Hello from nested! 2 x: 101
x = 132

Relevant background information

See Strange capture denial and acceptance for Anonymous Functions and Function refs on the Lazarus forums.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking