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);
}