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

Sven Barth pascaldragon at googlemail.com
Wed Dec 11 23:21:02 CET 2019

Am 09.12.2019 um 01:03 schrieb Blaise at blaise.ru:
> On 08.12.2019 22:30, Sven Barth wrote:
>> there is no official way to access such parameters
> 1) At the time of providing that answer on Stack Overflow, Barry Kelly 
> worked as a DCC developer. While it is not truly official, it is 
> pretty close, and satisfies my criterion of "fully conforming to the 
> ABI and particularities of the compiler".
> 2) That statement of yours is factually incorrect. Again.
>> there is no stock implementation in Delphi for *any* platform
> You remind me of a certain Rudy from the old EMBT forums. It is one 
> thing to not know something due to the lack of experience (with DCC), 
> but to keep insisting despite being repeatedly told otherwise takes an 
> admirable amount of self-confidence :P
> ----------8<----------
> procedure Foo; cdecl; varargs;
> var    Z: TVarArgList;
> begin
>     VarArgStart(Z);
>     writeln( VarArgGetValue(Z, Integer) );
>     writeln( VarArgGetValue(Z, PChar) );
>     VarArgEnd(Z)
> end;
> begin    {$AppType Console}
>     Foo(42, 'You know nothing')
> end.
> ----------8<----------

Well then, let's put this into Delphi 10.2 32-bit then, shall we?

=== output begin ===

[dcc32 Error] tvarargs.dpr(2): E2277 Only external cdecl functions may 
use varargs
[dcc32 Error] tvarargs.dpr(4): E2003 Undeclared identifier: 'VarArgStart'
[dcc32 Error] tvarargs.dpr(5): E2003 Undeclared identifer: 'VarArgGetValue'
[dcc32 Error] tvarargs.dpr(5): E2029 '(' expected but ')' found
[dcc32 Error] tvarargs.dpr(6): E2029 ',' or ')' expected but identifier 
'writeln' found
[dcc32 Error] tvarargs.dpr(6): E2029 '(' expected, but ')' found
[dcc32 Error] tvarargs.dpr(7): E2029 ',' or ')' expected but identifier 
'VarArgEnd' found

=== output end ===

And would you look at that: Delphi prohibits implementing "varargs" 
functions as well.

Note: I'm aware that the following code compiles:

=== code begin ===

   TTestFunc = reference to procedure(aStr: String) cdecl varargs;

   f1: TTestFunc;
   f1 := procedure(aStr: String) cdecl varargs

=== code end ===

But I assume this is a bug/oversight, because this compiles as well:

=== code begin ===

   TTestFunc = reference to procedure(aStr: String) register varargs;

   f1: TTestFunc;
   f1 := procedure(aStr: String) register varargs

=== code end ===

Note 2: your code wouldn't work anyway, because your VarArgGetValue() is 
incorrect. One can not directly pass a type to a non-compiler-magic 
function, so it either needs to be implemented using PTypeInfo as 
argument or by using a generic function (which Delphi only supports as 
members of a structured type, though that could be part of TVarArgList 

>> But only on i386-win32 and x86_64-win64. On Sys V ABI x86_64 targets 
>> there is no way around it, because the arguments are passed in 
>> registers, not in the stack area.
> Two mistakes on your part:
> 1) Much like SysV x64 ABI, Windows/x64 ABI does use registers for that.
> 2) Yet the non-stock solution still works, because DCC does support 
> VARARGS (which I keep telling you, but you keep arguing pointlessly), 
> so it spills the registers on the stack.

I wasn't clear enough again. With the Win64 ABI it works, because it is 
geared towards that: the caller must allocate the home space for the 
four registers and puts floating point values also into the integer 
registers. Then the callee can simply spill all integer registers to the 
home space and access them using pointers (but even that needs compiler 
support for varargs then, as the compiler might otherwise decide to 
spill something else into the home space).

For the Sys V ABI this does not work however, because there is no home 
space. The compiler detects the presence of the __builtin_vastart 
intrinsic and then spills all registers (integer and floating point) to 
the function's local frame. The __builtin_vanext intrinsic then needs to 
access either the spilled integer or floating point registers in the 
local frame or those values pass by the stack at a location *above* the 
return address.

>> your patch WILL NOT allow that
>> we DO NOT WANT to support this
> 1) There is really no need to shout.
> 2) One reason I intended to allow that with my patch is compatibility 
> with DCC. And I have only brought it up because your understanding of 
> what DCC actually allows appears consistently to be lacking.
> Should the team reject that aspect of my patch, I am not going to 
> throw a hissy fit and angrily fork into NewNewPascal :)
>>> And if I use the procvardef parser, I, like Jonas, would need to 
>>> prohibit "OF OBJECT" and "IS NESTED".
>> The code of procvar_dec as it is currently does not forbid it. So 
>> that will need to be improved anyway.
> Jonas prohibits them only when type constructor is used in a named 
> type definition. That is one of the bugs I mentioned in the first email.

That one took me a while to parse, but you mean that it's only checked 
in read_named_type, but not if it's using read_anon_type? That would 
indeed need to be fixed then.

Also it's a further reason to parse the function references using 
procvar_dec and delay the conversion to an interface cause the 
directives are handled later outside of read_named_type/read_anon_type 
(and as we've said for the sake of consistency "reference to procedure; 
<directive>;" should be allowed).

>> it's part of the specification (and I'm not arguing that!)
> You said, verbatim:
>> from the user's point of view an anonymous function variable is 
>> essentially a procvar as well
> The specification dictates that /your/ user should change his mental 
> model from procvar to interface reference :)
> And since "method reference types are interface types" is not only an 
> implementation detail but now a part of the specification, I feel that 
> parsing them as interfaces makes perfect sense.
> Anyhow, for the second time I am asking you to stop reviewing code 
> that has not been submitted. I would rather have feedback on 
> https://lists.freepascal.org/pipermail/fpc-devel/2019-December/042264.html 
> , which is kinda blocking me, and we have the subject issue blocking 3.2.

I hope to do this today (Wednesday) or at the latest tomorrow. Didn't 
have the time before now.

> @Jonas: Has the team decided on the amended syntax for C-block 
> references? I am ready to start implementing whichever.
Sorry for not notifying you.


More information about the fpc-devel mailing list