[fpc-devel] nestedprocvar questions

Jonas Maebe jonas.maebe at elis.ugent.be
Sun Aug 5 14:33:34 CEST 2012

On 31 Jul 2012, at 19:04, David Jenkins wrote:

> Some questions about 'nestedprocvars' mode switch
> We have a simplified version of the nested procedure calling demonstrated in tests/test/tmaclocalprocparam3d.pp.  It looks more or less like:
> {$mode DELPHI}
> {$modeswitch nestedprocvars}
> type
>  tnestedprocvar = function(AArg: string): boolean;
>  procedure p1(AArg: string; pp: tnestedprocvar);
>  begin
>    if pp(AArg) then
>      writeln('true');
>  end;
>  procedure q;
>    function r(AArg: string): boolean;
>    begin
>      writeln(AArg)
>      Result := true;
>    end;
>  begin
>     p1('test string', @r);
>  end;
> Notice that it is $MODE DELPHI, that the proc var is a function, and that we do not access any external variables in the nested function.
> Question #1:
> There seems to be an interaction between $MODE DELPHI and the 'is nested' construct.  I.e. I cannot put the 'is nested' after the tnestedprocvar type and do the function passing with '@r'.  If I do the compiler complains about getting a pointer (@r) when it was expecting a function (..): boolean is nested.  So either I remove the'@' and just pass 'r' or I do not include the 'is nested'.
> Is this correct?

@someproc in Delphi (and FPC Delphi mode) evaluates to an untyped pointer, rather than to a procvar type. Delphi (and FPC in Delphi mode) allow implicit type conversions from untyped pointers into regular procedure variables. Neither FPC nor Delphi allows doing this when assigning a value to a "procedure of object" though, because a "procedure of object" internally consists of two pointers and an untyped pointer only defines one of those. Since a "procedure is nested" internally also consists of two pointers, it cannot be done there either.

> Question #2:
> This code is being compiled both with Delphi compiler and with FPC.  Delphi handles the nesting with no problem and with no 'is nested' directive.
> Should nestedprocvar be included automatically with $MODE DELPHI for compatibility?

It is purely a coincidence that {$modeswitch nestedprocvars} currently changes the calling convention in a way that makes it compatible with Delphi as far as calling local functions that do not access parent's local variables or parameters. This is not guaranteed or intentional in any way, and may change in the future or on different platforms.

See also http://bugs.freepascal.org/view.php?id=9432 and the related bugs reports.

> Question #3:
> If we set up our code as above can we expect the compiler to be consistent in parameter set up for the next while?

As mentioned above: no.

> Question #4:
> If we set up our code as above (with no 'is nested') would it be safe to include access of an external variable (internal to procedure q) to the nested function?

It would be guaranteed to fail both in FPC and in Delphi. The code has no access to the nested frame pointer, which would be required for being able to access those variables.


More information about the fpc-devel mailing list