[fpc-devel] C-block reference syntax (blocker for 3.2)

Sven Barth pascaldragon at googlemail.com
Sat Dec 7 12:21:48 CET 2019

Am 07.12.2019 um 01:00 schrieb Blaise at blaise.ru:
> Beforehand, to provide a context, here are some excerpts from private 
> correspondence:
> On 11.12.2016 22:00:37 +0300, Blaise at blaise.ru wrote in 
> 1c51a35a-bbbc-c99d-232f-0bf6529dfd65 at blaise.ru:
>> my progress thus far
>> 9) Method reference directives are now allowed:
>>     type M = reference to procedure varargs cdecl;
>> DCC-style syntax is used
> On 27.06.2017 11:44:40 +0200, Sven Barth wrote in 
> CAFMUeB96Piu=ZntCLASvZM9_pYEkqscFOm_+iRbXJeoNekYpGw at mail.gmail.com:
>> the syntax for cblock references was selected on purpose to be 
>> compatible with the syntax for Delphi style "reference to" method 
>> pointers, only with "cdecl" as calling convention.
> On 10.02.2018 14:34:42 +0100, Sven Barth wrote in 
> d86fc6bb-789b-2963-55e9-16bd2a770c7e at googlemail.com:
>> It seems that anonymous functions do indeed support calling 
>> conventions... dang it... I had hoped to use the calling convention 
>> as a marker for the difference which is why I told Jonas to implement 
>> cblocks this way. But on the other hand I'd say that it is really 
>> unusual to use a calling convention with anonymous functions
> On 23.08.2019 06:54:21 +0200, Sven Barth wrote in 
> b1a88e8d-e11e-f430-8a90-2b0b0b27b384 at googlemail.com:
>> There isn't much use for "reference to XXX; cdecl;" in the field for 
>> normal anonymous functions. Yes, it works, but really, who uses it 
>> that way?
>> So the solution is simply to have "reference to XXX; cdecl;" be 
>> parsed as a cblock if modeswitch CBLOCKS is set and as a normal 
>> anonymous function reference otherwise. This way it can be controlled 
>> on a per-unit base.
> Counterpoints:
> 1) In my professional opinion, the current "solution" is a horrible 
> yucky hack: different (albeit similar) entities look exactly the same, 
> and they cannot be used simultaneously.
> 2) As a compiler developer, my job is to provide orthogonal building 
> blocks and ensure that every conceivable semantically valid 
> combination of them actually works. When one applies reasoning akin to 
> "who uses it that way", they inevitably reduce the power of a language 
> to a subset defined by their often limited understanding of what can 
> and should be possible.
> 3) My first example back in 2016 intentionally featured a valid use 
> case: CDECL is crucial for VARARGS. (Somehow, not only that case, but 
> the whole point that DCC accepts calling conventions went unnoticed.)

I stand by my point that the combination of anonymous function variables 
with calling conventions and cblocks occurs very, very seldomly.

1.) CBlocks are only supported on Mac OS X / macOS.
2.) Setting the calling convention for an anonymous function is only 
really useful for one specific case: simulating a COM/WinRT delegate 
which is essentially an interface with a single Invoke function (just 
like how anonymous functions are implemented) using the StdCall calling 
convention. Thus this would only really be required on Windows. And no, 
your argument with VarArgs does not count either: one can not access 
VarArgs parameters inside a Delphi/FPC function (without resorting to 
assembly). In fact they can only be safely used for external functions 
in FPC.

So there is no real overlap here. Even if the default calling convention 
should be set to pocall_cdecl one could check tprocdef.procoptions for 
po_hascallingconvention to decide this.

But if we want to change this syntax, we should definitely change this 
now before 3.2 is out of the door.

Am 07.12.2019 um 01:00 schrieb Blaise at blaise.ru:
> Jonas parses them via procvar_dec, and I parse closure reference types 
> via parse_proc_dec under 
> symtablestack.push(invokable_interface.symtable), and it makes perfect 
> sense since such types /are/ interfaces (to the point that they are 
> directly implementable on classes).

That is only how they are implemented. In fact you should parse the 
declaration using procvar_dec (with possible extensions/checks) as well, 
because that handles procvar specific functionality and from the user's 
point of view an anonymous function variable is essentially a procvar as 
well. Only afterwards you create an interface with an appropriate 
method. I thought I had written you this way back, but for the life of 
me I can't find that mail anymore...


More information about the fpc-devel mailing list