Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2003-04

fpgtk problem

15 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jeff Pohlmeyer

I finally decided to make an attmept at compiling fpc from the CVS sources. (fixes branch, 2003-04-01)

Everything went smooth, except for one small problem:

  fpgtk.pp(3032,57) Error: Illegal parameter list

The code in question is this:

  procedure TFPgtkObject.SignalEmit (aName:string; Args:array of const);
  begin
    gtk_signal_emit_by_name (TheGtkObject, pgchar(aName), Args);
  end;

Apparently the compiler is getting confused about exactly what a "const" is, when Args is passed from a regular function to a cdecl function.

At any rate, changing the declaration to this:

  procedure TFPgtkObject.SignalEmit (aName:string; Args:array of TVarRec);

- seems to solve (or at least hide) the problem.

__________________________________________________ Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com

Reply by email

Michael Van Canneyt
to Jeff Pohlmeyer
Jeff Pohlmeyer wrote 23 lines
I finally decided to make an attmept at compiling fpc from the CVS sources. (fixes branch, 2003-04-01) Everything went smooth, except for one small problem: fpgtk.pp(3032,57) Error: Illegal parameter list The code in question is this: procedure TFPgtkObject.SignalEmit (aName:string; Args:array of const); begin gtk_signal_emit_by_name (TheGtkObject, pgchar(aName), Args); end; Apparently the compiler is getting confused about exactly what a "const" is, when Args is passed from a regular function to a cdecl function. At any rate, changing the declaration to this: procedure TFPgtkObject.SignalEmit (aName:string; Args:array of TVarRec); - seems to solve (or at least hide) the problem.

It hides the problem.
It's a serious compiler problem which - unfortunately - cannot be solved easily.

Michael.

Reply by email

Pavel V. Ozerski
to Jeff Pohlmeyer: I finally decided to make an attmept at compiling fpc from the CVS sources. (fixes…

Hello Jeff,

Wednesday, April 02, 2003, 3:44:37 AM, you wrote:

JP> I finally decided to make an attmept at compiling fpc from the CVS sources. JP> (fixes branch, 2003-04-01)

JP> Everything went smooth, except for one small problem:

JP>   fpgtk.pp(3032,57) Error: Illegal parameter list

JP> The code in question is this:

JP>   procedure TFPgtkObject.SignalEmit (aName:string; Args:array of const);
JP>   begin
JP>     gtk_signal_emit_by_name (TheGtkObject, pgchar(aName), Args);
JP>   end;

JP> Apparently the compiler is getting confused about exactly what JP> a "const" is, when Args is passed from a regular function to a JP> cdecl function.

JP> At any rate, changing the declaration to this:

JP>   procedure TFPgtkObject.SignalEmit (aName:string; Args:array of TVarRec);

JP> - seems to solve (or at least hide) the problem.

JP> __________________________________________________ JP> Do you Yahoo!?
JP> Yahoo! Tax Center - File online, calculators, forms, and more JP> http://tax.yahoo.com
JP> _______________________________________________ JP> fpc-devel maillist -
JP> http://lists.freepascal.org/mailman/listinfo/fpc-devel

Did you test also {$Mode Delphi}?

Best regards, Pavel

Reply by email

Peter Vreman
to Pavel V. Ozerski
Show quoted text 26 lines
JP> I finally decided to make an attmept at compiling fpc from the CVS sources. JP> (fixes branch, 2003-04-01) JP> Everything went smooth, except for one small problem: JP> fpgtk.pp(3032,57) Error: Illegal parameter list JP> The code in question is this: JP> procedure TFPgtkObject.SignalEmit (aName:string; Args:array of const); JP> begin JP> gtk_signal_emit_by_name (TheGtkObject, pgchar(aName), Args); JP> end; JP> Apparently the compiler is getting confused about exactly what JP> a "const" is, when Args is passed from a regular function to a JP> cdecl function. JP> At any rate, changing the declaration to this: JP> procedure TFPgtkObject.SignalEmit (aName:string; Args:array of TVarRec); JP> - seems to solve (or at least hide) the problem. Did you test also {$Mode Delphi}?

That will not solve the problem. The problem is that there is no knowledge how to push an array with X elements of a certain type to a C function. The compiler does not know anything at compile time and can't generate the correct code for it. Having a cdecl function with array of const has even less knowledge how much arguments are pushed since there is no length that in C it is also not possible to call printf(format,...) with the arguments passed to function with variable arguments like trace_msg(format,...)

Peter

Reply by email

KJK::Hyperion
to Peter Vreman

At 17.13 02/04/2003, you wrote:
[...]

That will not solve the problem. The problem is that there is no knowledge how to push an array with X elements of a certain type to a C function.

what? it's the simplest thing in the world. You loop through all the elements of the TVarRec array, last to first, and push them on the stack, then you push the formal arguments. Sure, it generates a lot of code, but it's not that hard. I mean, variable arrays store the length and TVarRec stores the type of the data, is there something I don't get?

Pseudo code:

var
  Integer i, l;
l:= Length(Array);
for i:= l - 1 downto 0 do
  Push(Array[i]);
(* known at compile time *)
PushFormalParams();
CallFunction();
(* FormalParamsSize known at compile time *)
Pop(l + FormalParamsSize);

Reply by email

Peter Vreman
to KJK::Hyperion
Show quoted text 11 lines
At 17.13 02/04/2003, you wrote: [...] >That will not solve the problem. The problem is that there is no > knowledge >how to push an array with X elements of a certain type to a C function. what? it's the simplest thing in the world. You loop through all the elements of the TVarRec array, last to first, and push them on the stack, then you push the formal arguments. Sure, it generates a lot of code, but it's not that hard. I mean, variable arrays store the length and TVarRec stores the type of the data, is there something I don't get?

How about data conversions like shortstring, floats? And also there is a difference between pascal and C if the value or the address where the value is stored is pushed.

Reply by email

KJK::Hyperion
to Peter Vreman
you wrote 6 lines
>what? it's the simplest thing in the world. You loop through all the >elements of the TVarRec array, last to first, and push them on the stack, >then you push the formal arguments. Sure, it generates a lot of code, but >it's not that hard. I mean, variable arrays store the length and TVarRec >stores the type of the data, is there something I don't get? How about data conversions like shortstring, floats?

The Push() function in my pseudo-code is supposed to take care of that. And Borland null-terminates short strings for a reason

And also there is a difference between pascal and C if the value or the address where the value is stored is pushed.

Are you sure? I think there doesn't need to be any difference. Again, I think the Borland compiler already takes this in account

Reply by email

Peter Vreman
to KJK::Hyperion
Show quoted text 13 lines
At 07.18 03/04/2003, you wrote: >>what? it's the simplest thing in the world. You loop through all the >>elements of the TVarRec array, last to first, and push them on the >> stack, >>then you push the formal arguments. Sure, it generates a lot of code, >> but >>it's not that hard. I mean, variable arrays store the length and TVarRec >>stores the type of the data, is there something I don't get? >How about data conversions like shortstring, floats? The Push() function in my pseudo-code is supposed to take care of that. And Borland null-terminates short strings for a reason

You can't use a function to push the values, because returning from the function will cleanup the stack.

Show quoted text 5 lines
>And also there is a difference between pascal and C if the value or the >address where the value is stored is pushed. Are you sure? I think there doesn't need to be any difference. Again, I think the Borland compiler already takes this in account

Sorry i don't understand what you want to make clear here. There is no Borland compiler used at all.

Reply by email

KJK::Hyperion
to Peter Vreman: You can't use a function to push the values, because returning from the function will…
you wrote
You can't use a function to push the values, because returning from the function will cleanup the stack.

first, it was just pseudo-code. Second, Exit isn't a true function either. Nor Break. Nor WriteLn. Third, my point is that, despite it generates a lot of inline code, it isn't certainly impossible. And, fourth and last, I add: just like now there is a pseudo-type called "array of const" that the compiler handles in a special way, I don't see why there can't be a pseudo-type "TVAList" as well. FreePascal isn't interested in ISO compliance, right? so why bother?

Show quoted text 6 lines
>>And also there is a difference between pascal and C if the value or the >>address where the value is stored is pushed. >Are you sure? I think there doesn't need to be any difference. Again, I >think the Borland compiler already takes this in account Sorry i don't understand what you want to make clear here. There is no Borland compiler was just saying that Delphi can pass arguments to C/C++ code flawlessly

(apart from ellipses) and in the exact manner you'd expect, so I don't see why FreePascal can't

Reply by email

Florian Klaempfl
to KJK::Hyperion: first, it was just pseudo-code. Second, Exit isn't a true function either. Nor Break. Nor…
I was just saying that Delphi can pass arguments to C/C++ code flawlessly (apart from ellipses) and in the exact manner you'd expect, so I don't see why FreePascal can't

The point is, we're talking about passing parameters to ellipses :)

But I think we could provide a solution: the types in the array of const (if the function isn't cdecl'ed, of course) are excatly known because of the info in the tvarrec as well as the size of the array of const. So we can map it to the appropriate C types using either an assembler helper function or some inline code, but I don't know if it is worth the effort to implement this.

Reply by email

Peter Vreman
to KJK::Hyperion: first, it was just pseudo-code. Second, Exit isn't a true function either. Nor Break. Nor…
you wrote 11 lines
At 07.41 04/04/2003, you wrote: >You can't use a function to push the values, because returning from the >function will cleanup the stack. first, it was just pseudo-code. Second, Exit isn't a true function either. Nor Break. Nor WriteLn. Third, my point is that, despite it generates a lot of inline code, it isn't certainly impossible. And, fourth and last, I add: just like now there is a pseudo-type called "array of const" that the compiler handles in a special way, I don't see why there can't be a pseudo-type "TVAList" as well. FreePascal isn't interested in ISO compliance, right? so why bother?

We talked internally about adding support for va_start, va_end and the va_list type. But that wouldn't solve the problem for fpgtk since those functions don't get a va_list.

The problem with the fpgtk code is that it were macro's in C. And there is no possibility to have an exact function equivalent for it except support also macro's

Show quoted text 10 lines
>>>And also there is a difference between pascal and C if the value or the >>>address where the value is stored is pushed. >>Are you sure? I think there doesn't need to be any difference. Again, I >>think the Borland compiler already takes this in account >Sorry i don't understand what you want to make clear here. There is no >Borland compiler used at all. I was just saying that Delphi can pass arguments to C/C++ code flawlessly (apart from ellipses) and in the exact manner you'd expect, so I don't see why FreePascal can't

We can also pass arguments to C code flawlessly apart from the ellipses

Peter

Reply by email

KJK::Hyperion
to Florian Klaempfl: The point is, we're talking about passing parameters to ellipses :) But I think we could…
you wrote
>I was just saying that Delphi can pass arguments to C/C++ code flawlessly >(apart from ellipses) and in the exact manner you'd expect, so I don't >see why FreePascal can't The point is, we're talking about passing parameters to ellipses :)

I thought we were talking about how the parameters are actually passed on the stack...

So we can map it to the appropriate C types using either an assembler helper function or some inline code,

yes, that's what I said

Reply by email

KJK::Hyperion
to Peter Vreman: We talked internally about adding support for va_start, va_end and the va_list type. But…
you wrote
We talked internally about adding support for va_start, va_end and the va_list type. But that wouldn't solve the problem for fpgtk since those functions don't get a va_list.

well, TVarArgs (better name - TVAList should correspond to va_list) is just how it would appear to a Pascal program. What I meant was this:

function printf(fmt: PChar; args: TVarArgs = []); cdecl; external;

and you call it as:

printf('%s() failed: %d'#0A, ['blah', errno]);

The compiler treats the TVarArgs parameter specially, as a hint to translate the open array constructor into a list of arguments to be pushed on the stack. I agree that this sucks, and that supporting the implicit conversion of an array of TVarRec into a TVarArgs would suck even more, but it's an idea

The problem with the fpgtk code is that it were macro's in C.

ouch

And there is no possibility to have an exact function equivalent for it except support also macro's

I suggest you to have a look at the C++ library Boost, and in particular at its "bind" template. It allows you to statically create function objects that, at runtime, call the function they're "bound" to, with parameters specified at compile time. I know FreePascal is far from that, but it's a cool concept

Reply by email