digitalmars.D - importC reflection drop const attribute bugs
for this test case: test2i.c ```c typedef struct Message Message; int tryEncode(const Message* msg); ``` test2d.d ```d import test2i; extern(C) int main(int argc, char** argv){ doTest!test2i(); return 0; } void doTest(alias M)(){ static foreach(symbol; __traits(allMembers, M)) if( true ) { static if( __traits(compiles, typeof(__traits(getMember, M, symbol))) ) { alias T = typeof(__traits(getMember, M, symbol)); static if( is( T == function) ) { pragma(msg, symbol, "\t", T); } } } } ``` ```sh dmd --version DMD64 D Compiler v2.107.1-rc.1 Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved written by Walter Bright dmd test2d.d -betterC tryEncode extern (C) int(Message* msg) ``` the output should be `tryEncode extern (C) int(const(Message)* msg)` ============= there is one more bugs: if I pass T as alias to template, I will loss parameters name. (ParameterIdentifierTuple return empty string)
Feb 27
On Tuesday, 27 February 2024 at 12:23:40 UTC, Dakota wrote:for this test case: test2i.c ```c typedef struct Message Message; int tryEncode(const Message* msg); ``` [...]I dont know how to find it by DustMite, take 5 hours to find this bugs. (find from a 700KB c header files)
Feb 27
On Tuesday, 27 February 2024 at 12:27:01 UTC, Dakota wrote:I dont know how to find it by DustMite, take 5 hours to find this bugs. (find from a 700KB c header files)This test case more clear: test2i.c ```c typedef struct Message Message; int tryEncode(const Message* msg); ``` test2d.d ```d import test2i; void test1(){ const Message* m; tryEncode(m); } ``` ```sh dmd test2d.d -betterC -c test2d.d(4): Error: function `tryEncode` is not callable using argument types `(const(Message*))` test2d.d(4): cannot pass argument `m` of type `const(Message*)` to parameter `Message* msg` test2i.c(2): `test2i.tryEncode(Message* msg)` declared here ```
Feb 27
On Wednesday, 28 February 2024 at 05:00:32 UTC, Dakota wrote:[...]I reported this as a bug before: https://issues.dlang.org/show_bug.cgi?id=23926 It’s actually not clear what the solution should be as D const is not the same as C const as D const is transitive. Walter decided to err on the side of accepting more code, so C const is translated to D non-const.
Feb 27
On Wednesday, 28 February 2024 at 05:13:19 UTC, Dave P. wrote:On Wednesday, 28 February 2024 at 05:00:32 UTC, Dakota wrote:Sounds like just removing const on the D side should work? ```d import test2i; void test1() { Message* m; tryEncode(m); } extern(C) void main() { test1(); } ```[...]I reported this as a bug before: https://issues.dlang.org/show_bug.cgi?id=23926 It’s actually not clear what the solution should be as D const is not the same as C const as D const is transitive. Walter decided to err on the side of accepting more code, so C const is translated to D non-const.
Feb 27
On Wednesday, 28 February 2024 at 05:13:19 UTC, Dave P. wrote:On Wednesday, 28 February 2024 at 05:00:32 UTC, Dakota wrote:Thanks for the tips. I am work on a big code base, it use C const as transitive( so the function accept const will not change the pointer field). `C const translated to D non-const` not a good solution for me. I suggestion add a dmd flags to change the behavior, like `--importC-const-pointer=`. so the user can choice what kind behavior they want. some project use transitive const in C, so they can work with this new options. One more options is translate it into a user-defined template, this is more flexible. user can return diff result base on the name. for example: ```c typedef struct Message Message; int tryEncode(const Message* msg); ``` => ```d struct Message; int tryEncode(importConstPointer!(Message)* msg); ```[...]I reported this as a bug before: https://issues.dlang.org/show_bug.cgi?id=23926 It’s actually not clear what the solution should be as D const is not the same as C const as D const is transitive. Walter decided to err on the side of accepting more code, so C const is translated to D non-const.
Feb 27