Bug 23926 – ImportC: D can’t pass pointer to const struct to C function declared taking pointer to const struct

Status
RESOLVED
Resolution
LATER
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-05-18T16:39:39Z
Last change time
2024-02-28T15:20:32Z
Keywords
ImportC
Assigned to
No Owner
Creator
dave287091

Comments

Comment #0 by dave287091 — 2023-05-18T16:39:39Z
// foo.c struct Foo; void foo(const struct Foo* x); // usefoo.d import foo; void bar(const Foo* x){ //Error: function `foo.foo(Foo* x)` is not callable using argument types `(const(Foo*))` // cannot pass argument `x` of type `const(Foo)*` to parameter `Foo* x` foo.foo(x); } I believe const was stripped so that C function bodies could be compiled, but it should be preserved for the purpose of calling from D.
Comment #1 by dave287091 — 2023-05-18T19:59:26Z
Thinking more about this, C doesn’t have transitive const so maybe this is actually correct. Maybe D needs head const to properly express C const.
Comment #2 by dave287091 — 2023-05-18T20:00:16Z
(In reply to dave287091 from comment #1) > Thinking more about this, C doesn’t have transitive const so maybe this is > actually correct. Maybe D needs head const to properly express C const. The error message could be improved though.
Comment #3 by bugzilla — 2023-05-23T05:25:53Z
You're right, it's about the non-transitivity of C const. D's choices are: 1. compile correct C code, and also compile some incorrect C code 2. not compile some correct C code, not compile incorrect C code 3. implement non-transitive const in D (1) is the most pragmatic choice. Maybe eventually we can do (3), but it's a low priority. Note that any hand-translated C code to D has the same issue. Improving the error message also would be rather clumsy. I wish I had better news on that. BTW, `const struct Foo*` in C looks like const(Foo)* in D, while `const Foo*` in D is actually `const(Foo*)`. I'm going to resolve this as "LATER".
Comment #4 by lance — 2024-02-28T15:20:32Z
Can this be resolved by having ImportC generate a D overload? If const struct Foo* is rewritten to Foo*, it should. This is a solution for this particular example: struct Foo; void foo(Foo* x) {} // ImportC generates this function when encountering const struct Foo* void foo(const(Foo)* x) { foo(cast(Foo*) x); } void bar(const Foo* x) { foo(x); }