Recent

Author Topic: C-Bindings --> Const vs. Constref  (Read 472 times)

Zvoni

  • Sr. Member
  • ****
  • Posts: 433
C-Bindings --> Const vs. Constref
« 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?
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 818
Re: C-Bindings --> Const vs. Constref
« Reply #1 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);

Zvoni

  • Sr. Member
  • ****
  • Posts: 433
Re: C-Bindings --> Const vs. Constref
« Reply #2 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
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

korba812

  • Full Member
  • ***
  • Posts: 143
Re: C-Bindings --> Const vs. Constref
« Reply #3 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);

Zvoni

  • Sr. Member
  • ****
  • Posts: 433
Re: C-Bindings --> Const vs. Constref
« Reply #4 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)
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

PascalDragon

  • Hero Member
  • *****
  • Posts: 2603
  • Compiler Developer
Re: C-Bindings --> Const vs. Constref
« Reply #5 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