Lazarus

Free Pascal => General => Topic started by: Zvoni on November 04, 2020, 07:43:36 pm

Title: C-Bindings --> Const vs. Constref
Post by: Zvoni on November 04, 2020, 07:43:36 pm
Hi Folks,

currently i'm testing my C-Bindings i've written for a c-lib.

And yes, i admit, i missed the Paragraph on the Wiki "Pascal for C Users", where it states that i should use constref, but now i'm confused as hell.
https://wiki.freepascal.org/Pascal_for_C_users
https://wiki.freepascal.org/Constref
Example:
Code: C  [Select][+][-]
  1. void A_C_Procedure1(const AStruct *m);
  2. void A_C_Procedure2(AStruct *m);
  3.  
What's the correct form now?
Code: Pascal  [Select][+][-]
  1. PMyStruct = ^TMyStruct;
  2. TMyStruct = Record
  3. End;
  4.  
  5. Procedure A_C_Procedure1(constref m:TMyStruct);  //Note "T" vs "P"
  6. Procedure A_C_Procedure2(var m:TMyStruct); //Note "T" vs "P"
  7. //Or
  8. Procedure A_C_Procedure1(const m:PMyStruct);  //Note "T" vs "P"
  9. Procedure A_C_Procedure2(m:PMyStruct); //Note "T" vs "P"
  10.  
Why would the compiler decide to pass a Const-Argument as value if it's declared as a Pointer?
What's the correct way?
Title: Re: C-Bindings --> Const vs. Constref
Post by: Jonas Maebe on November 04, 2020, 07:48:02 pm
All of you declarations are correct. The remark about the compiler passing a const record by value applies only to
Code: [Select]
Procedure A_C_Procedure1(const m:TMyStruct); cdecl;

The reason is that in this declaration, the C compiler also passes the struct by value:
Code: [Select]
void A_C_Procedure1(const AStruct m);
Title: Re: C-Bindings --> Const vs. Constref
Post by: Zvoni on November 04, 2020, 08:30:09 pm
Jonas,
thx for clearing that up.
So, basically: If it's a pointer, the compiler doesn't optimize it away.
Uff, was worried i had to rewrite everything
Title: Re: C-Bindings --> Const vs. Constref
Post by: korba812 on November 04, 2020, 09:48:07 pm
For "Procedure A_C_Procedure2(var m:TMyStruct)", function parameter must be a variable. In the case of "Procedure A_C_Procedure2(m:PMyStruct)" it is possible to specify nil as the parameter value:  A_C_Procedure2(nil);
Title: Re: C-Bindings --> Const vs. Constref
Post by: Zvoni on November 05, 2020, 08:28:35 am
korba,

nice catch.
Didn't think about that, but you're right.
Nil is often passed to an init-procedure when expecting an initialized structure back (with the Pointer/struct being created/initialized inside that procedure, with Return-Type as Int indicating success/failure)
Title: Re: C-Bindings --> Const vs. Constref
Post by: PascalDragon on November 05, 2020, 08:53:37 am
If you know that the C code errors out if you pass Nil then you can use var, out or constref instead of a pointer type. If not it's better to use a pointer type so that the user can indeed pass Nil.

Though it is allowed to do this even for var parameters:
Code: Pascal  [Select][+][-]
  1. A_C_Procedure2(PMyStruct(Nil)^);
TinyPortal © 2005-2018