digitalmars.D.learn - CTFE and BetterC compatibility
- Claude (74/74) Apr 27 2022 Hello,
- Andrea Fontana (3/4) Apr 27 2022 Dynamic arrays are not supported using -betterC
- Stanislav Blinov (7/18) Apr 27 2022 On Wednesday, 27 April 2022 at 14:21:15 UTC, Claude wrote:
- Claude (10/16) Apr 27 2022 That's what I was afraid of... Thanks for the link to the
- rikki cattermole (37/37) Apr 27 2022 This works:
- Claude (10/11) Apr 27 2022 Cool, thanks.
- Adam D Ruppe (31/33) Apr 27 2022 In that case, you want to prove to the compiler it is only called
- bauss (2/3) Apr 28 2022 A tale as old as time itself
- Dennis (5/8) Apr 28 2022 In this case, it was actually a trailing whitespace in the
- Adam D Ruppe (2/4) Apr 28 2022 Stefan's own `assert(__ctfe);` approach was better anyway...
- bauss (3/13) Apr 28 2022 The fact a trailing white-space has any impact is almost
Hello, I want to make a SAX XML parser in D that I could both use at run-time or compile-time. Also when I use it at compile-time, I would like to use BetterC so I don't have to link D-runtime. But I have some compilation problems. I use GDC (GCC 9.4.0). Here's a reduced sample code: ``` struct Data { int[] digits; } int parseDigit(char c) pure { return c - '0'; } Data parse(string str) pure { Data data; while (str.length != 0) { // Skip spaces while (str[0] == ' ') str = str[1 .. $]; // Parse single digit integer data.digits ~= parseDigit(str[0]); // Consume digit str = str[1 .. $]; } return data; } enum Data parsedData = parse("5 4 2 6 9"); extern(C) int main() { pragma(msg, "First digit=", parsedData.digits[0]); return 0; } ``` If I compile and link against D-runtime, it works: ``` $ gcc test.d -lgdruntime -o test First digit=5 ``` If I compile with BetterC (no D-runtime for GDC), I get a compilation error about RTTI: ``` $ gcc test.d -fno-druntime -o test test.d: In function ‘parse’: test.d:25:21: error: ‘object.TypeInfo’ cannot be used with -fno-rtti 25 | data.digits ~= parseDigit(str[0]); | ^ ``` If I compile without the BetterC switch, compilation actually works but I'll have some linker issues: ``` $ gcc test.d -o test First digit=5 /tmp/ccuPwjdv.o : In function « _D5test5parseFNaAyaZS5test4Data » : test.d:(.text+0x137) : undefined reference to « _d_arraybounds » test.d:(.text+0x183) : undefined reference to « _d_arraybounds » etc... ``` The operation requiring the D-runtime is appending the array, but it should **only** be done at compile-time. I don't understand why it requires to link against the D-runtime whereas it only needs it at compilation-time (and the compilation and CTFE interpretation works, as we can see in the last example). Is there a way to force the compiler to not emit any object ode for those functions? Or am I missing something? Regards, Claude
Apr 27 2022
On Wednesday, 27 April 2022 at 14:21:15 UTC, Claude wrote:data.digits ~= parseDigit(str[0]);Dynamic arrays are not supported using -betterC Andrea
Apr 27 2022
On Wednesday, 27 April 2022 at 14:21:15 UTC, Claude wrote: This is a long-standing pain point with BetterC (see https://issues.dlang.org/show_bug.cgi?id=19268). As for this:If I compile without the BetterC switch, compilation actually works but I'll have some linker issues: ``` $ gcc test.d -o test First digit=5 /tmp/ccuPwjdv.o : In function « _D5test5parseFNaAyaZS5test4Data » : test.d:(.text+0x137) : undefined reference to « _d_arraybounds » test.d:(.text+0x183) : undefined reference to « _d_arraybounds » etc... ```When not using BetterC, but not linking against druntime either, you have to provide your own implementation for those functions. This is e.g. so you can replace druntime with your own version.
Apr 27 2022
On Wednesday, 27 April 2022 at 14:27:43 UTC, Stanislav Blinov wrote:This is a long-standing pain point with BetterC (see https://issues.dlang.org/show_bug.cgi?id=19268).That's what I was afraid of... Thanks for the link to the bug-report. On Wednesday, 27 April 2022 at 14:27:43 UTC, Stanislav Blinov wrote:When not using BetterC, but not linking against druntime either, you have to provide your own implementation for those functions. This is e.g. so you can replace druntime with your own version.Yeah... The problem is that there will a lot of those functions to define (for a whole XML parser). I suppose I can use cork functions with empty bodies?? I will check if the linker optimize them out...
Apr 27 2022
This works: ```d struct Data { int[] digits; } int parseDigit(char c) pure { return c - '0'; } Data parse(string str) pure { Data data; if (__ctfe) { size_t used; data.digits.length = str.length; while (str.length != 0) { // Skip spaces while (str[0] == ' ') str = str[1 .. $]; // Parse single digit integer data.digits[used++] = parseDigit(str[0]); // Consume digit str = str[1 .. $]; } data.digits = data.digits[0 .. used]; } return data; } enum Data parsedData = parse("5 4 2 6 9"); extern(C) int main() { pragma(msg, "First digit=", parsedData.digits[0]); return 0; } ```
Apr 27 2022
On Wednesday, 27 April 2022 at 14:34:27 UTC, rikki cattermole wrote:This works:Cool, thanks. Unfortunately, with that implementation, I need to know the maximum size for the array. It works for that particular example, but in the context of an XML file analysis, it's a bit awkward. Regarding my comment above, I tried using cork functions for missing symbols: it also works! However the linker does not optimize those functions out (I see the symbols in the executable binary)...
Apr 27 2022
On Wednesday, 27 April 2022 at 14:21:15 UTC, Claude wrote:The operation requiring the D-runtime is appending the array, but it should **only** be done at compile-time.In that case, you want to prove to the compiler it is only called at compile time by encapsulating the function inside a template or defining it immediately where it is called. Delete the stand-alone function `parse` and instead call it like this: ``` // define it.... enum Data parsedData = function Data (string str) pure { Data data; while (str.length != 0) { // Skip spaces while (str[0] == ' ') str = str[1 .. $]; // Parse single digit integer data.digits ~= parseDigit(str[0]); // Consume digit str = str[1 .. $]; } return data; } ("5 4 2 6 9"); // and call it in the same place ``` Or if you want it to be independently defined still, you can define it inside a helper template but you'd have to return a basic type instead of Data, so I think calling it immediately is what you want to do here. There was going to be a ctfe-only thing you could put in the function so the compiler doesn't try to generate the runtime version, but this got killed due to internal D politics. A pity.
Apr 27 2022
On Wednesday, 27 April 2022 at 15:40:49 UTC, Adam D Ruppe wrote:but this got killed due to internal D politics. A pity.A tale as old as time itself
Apr 28 2022
On Thursday, 28 April 2022 at 12:10:44 UTC, bauss wrote:On Wednesday, 27 April 2022 at 15:40:49 UTC, Adam D Ruppe wrote:In this case, it was actually a trailing whitespace in the changelog entry making the test suite fail, but the PR author ceased activity before fixing it and now it has merge conflicts. https://github.com/dlang/dmd/pull/11014#discussion_r427108067but this got killed due to internal D politics. A pity.A tale as old as time itself
Apr 28 2022
On Thursday, 28 April 2022 at 12:36:56 UTC, Dennis wrote:In this case, it was actually a trailing whitespace in the changelog entry making the test suite fail, but the PR authorStefan's own `assert(__ctfe);` approach was better anyway...
Apr 28 2022
On Thursday, 28 April 2022 at 12:36:56 UTC, Dennis wrote:On Thursday, 28 April 2022 at 12:10:44 UTC, bauss wrote:The fact a trailing white-space has any impact is almost laughable.On Wednesday, 27 April 2022 at 15:40:49 UTC, Adam D Ruppe wrote:In this case, it was actually a trailing whitespace in the changelog entry making the test suite fail, but the PR author ceased activity before fixing it and now it has merge conflicts. https://github.com/dlang/dmd/pull/11014#discussion_r427108067but this got killed due to internal D politics. A pity.A tale as old as time itself
Apr 28 2022