Pass D const pointer to opaque C library: Guarantees? Optimization-safe?

Mike Parker aldacron at gmail.com
Sat Dec 16 11:19:36 UTC 2017


On Saturday, 16 December 2017 at 08:56:59 UTC, SimonN wrote:
> Hi,
>
> I'm calling a C library through a D wrapper. The situation is 
> like this:
>
> C library has:
>     struct A      { ... };
>     A* create_a() { ... }
>     void foo(A*)  { ... }
>
> D wrapper declares:
>     extern (C) {
>         struct A {}
>         A* create_a();
>         void foo(A*);
>     }

Just a nitpick, because sometimes the distinction matters: that's 
a binding, not a wrapper.


>
> The memory of the A is allocated by the C library. All the D 
> code ever sees is a pointer, an opaque handle to the resource. 
> How will the compiler optimizations behave around this:
>
> Question 1. Is that cast still safe in usercode if foo(a) 
> changes some internal values in *a that are undetectable 
> through the C API?

Not sure what you mean by "safe" in this context, but the mandate 
of const in D is that data will not change through that 
particular reference. It says nothing about what happens through 
other references to the same data, whether they be in D or C. If 
it's important to you that no data in an instance of A changes, 
then you'll have to audit the C functions to make sure they 
aren't changing anything. If it's not important, i.e. you only 
want to prevent changes on the D side and don't care if they 
happen on the C side, then that's fine.

>
> Question 2. If yes, can the wrapper sanely declare foo(const 
> A*) instead of foo(A*)?

In D, const function parameters serve as a bridge between mutable 
and immutable variables -- this particular implementation would 
accept A*, const A*, and immutable A*. For most purposes, on a C 
function binding it's nothing more than an annotation. Where it 
matters is if you pass immutable variables to the function -- if 
the parameter is const even when the function modifies the 
variable, D will allow immutable to be passed and you're looking 
at unexpected behavior.

So I would say it's not a good idea in the general case. Only add 
const to parameters in C function declarations if the C API 
actually declares those parameters as const.

>
> My use case: My const-heavy D usercode calls Allegro 5, a C 
> game/multimedia library without any const in its API, through 
> the D bindings DAllegro5. I'm considering to make a PR 
> implementing question 2. Github issue: 
> https://github.com/SiegeLord/DAllegro5/issues/42

I would expect SiegeLord to reject such a PR. I know I would if 
someone submitted one to any Derelict packages. I suggest making 
wrapper functions for your specific use case (hence my insistence 
on the distinction above), preferably combining mutliple function 
calls into one where it makes sense. Since you know if you're 
using immutable variables or not and when it's fine to cast away 
const, you can make the parameters to the wrapper functions const 
and cast it  away inside.





More information about the Digitalmars-d-learn mailing list