[fpc-pascal] cdecl calling and const parameters - was SizeOf(File) <> SizeOf(FileRec)

Tomas Hajny XHajT03 at mbox.vol.cz
Wed May 25 11:00:02 CEST 2005

Date sent:      	Wed, 25 May 2005 09:29:00 +0200
From:           	Søren Ager <sorenager at poboxes.com>
To:             	FPC-Pascal users discussions <fpc-pascal at lists.freepascal.org>
Subject:        	[fpc-pascal] cdecl calling and const parameters - was SizeOf(File)
	<> SizeOf(FileRec)
Send reply to:  	FPC-Pascal users discussions <fpc-pascal at lists.freepascal.org>
	<mailto:fpc-pascal-request at lists.freepascal.org?subject=unsubscribe>
	<mailto:fpc-pascal-request at lists.freepascal.org?subject=subscribe>

> > I believe the C const construct (const declaration in a call marked
> > as cdecl) is wrongly used in so32dll.connect (the meaning of this
> > construct in C is different from the Pascal "const" modifier).
> I am programming in Pascal so I can't see what C has to do with it ;-)

You expect them to behave the same way as you're used to from Pascal, 
but ask FPC to call the function in a way compatible to C by using a 
cdecl modifier. ;-) Yes, the meaning of a cdecl modifier is somewhat 
different in FPC from some other Pascal compilers - but it's designed 
so for better compatibility with those C compilers?

> I am only interested in changing the caling convention - not the
> meaning of the const which should be the same as var - with the
> exception that you are not allowed to change the parameter. So you are
> saying there is no way to make it behave like that? :-(
> > If address of the record should be passed, use either "var" modifier
> That works - but it is not optimal as I have to double buffer all
> calls in the standard units from const to var. Sockets.pas:
> Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean;
> var
>    sa : so32dll.SockAddr;
> begin
>    sa:=so32dll.SockAddr(Addr);
>    Connect:=so32dll.Connect(Sock,sa,AddrLen)=0;
>    if not Connect then
>      SocketError:=so32dll.sock_errno
>    else
>      SocketError:=0;
> end;

My suggestion would be:

1) Provide the (relevant) library calls in so32dll.pas with two 
(overloaded) versions, one with the more C-like approach using 
pointers, the other more pascallish with var pointers.

2) Use the pointer version in sockets.pas - that's perfectly 
compatible to the const parameters and is by the way the same what's 
done for the Unix implementations using C library - 
/rtl/inc/stdsock.inc (Unix implementations using kernel syscalls have 
different calling convention).

> And it gets worse when I have an untyped buffer (as send does) - then
> I will have to allocate memory - copy the contents - call the dll -
> deallocate...

Actually, it gets better there. ;-) Parameters cannot be passed on 
stack if they are untyped, so they are passed by reference as 
expected by you. That's another potential solution to your issue, 
although I wouldn't recommend discarding the types in declarations in 
cases these are known (e.g. in Connect), because that would remove 
the advantage of Pascal type checking.


More information about the fpc-pascal mailing list