Re: Completing C code with D style
On Wednesday, 10 November 2021 at 06:47:32 UTC, forkit wrote: btw. My pc has 24GB of main memory, and my CPU 8MB L3 cache. So I really don't give a damn about allocations .. not one little bit ;-) That's not the point. The point is the program is doing unnecessary non-trivial work while introducing additional failure paths. It certainly has ways to go to reach Ali's AA solution, but still... To put things in perspective, the algorithm can easily complete before malloc even returns (heck, before it even starts executing). There's what, 11 cmovs at most? It would take several dozen instructions, a couple of loops and a few other branches just to find malloc when you first call it. Not to mention it itself making that syscall and setting up its bins... And I'm not even talking about optimization. Just, uh, non-pessimization.
Re: Can we do system calls like that in D?
On Tuesday, 9 November 2021 at 12:28:59 UTC, Adam D Ruppe wrote: I'd be very easy to do that as a library mixin. You'd write @syscall(45) void whatever(); mixin BindSyscalls; and then the library generates the bodies as inline asm. Hello Adam! Well this is not exactly the behavior I was looking for, you see in this solution, there are two problems: 1. The mixins will get generated by the compiler (if I'm not mistaken) so it will worsen the compilation times VS if it was a simple function like in Vox. 2. I don't care about the syntax, neither than the fact that you can give the function an name you want (aliases can be used for that) but for the fact that with these way in Vox, you don't have to manually write inline assembly. It seems that I'm out of luck so inline assembly, here I go (unfortunately)! Thanks for your time and have a great day!
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 13:44:04 UTC, Steven Schveighoffer wrote: It seems like it should work. Figuring out the "lines" for things is really difficult in this expanded format, even though I know why it does that. I think importC should possibly allow printing of the actual source line along with the explicit source file/line, because knowing the vagrancies of the preprocessor is not going to be something that's easy to deal with, and you want to see what raw format is being passed to the compiler. [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63#file-tomld-c-L1439) is where "line 39" of toml.c is. [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63#file-tomld-c-L763) is where the definition of `malloc` is. To me, this looks reasonable. I narrowed it down to the following file, and it builds with gcc and ldc2 on my system. I don't have support for DMD, as this is an Arm system, but on another system, I can confirm that DMD 2.098.0 does not compile this: ```c typedef long unsigned int size_t; extern void *malloc (size_t __size) ; static void* (*ppmalloc)(size_t) = malloc; ``` I used `dmd -c testc.c`, `gcc -c testc.c` and `ldc2 -c testc.c`. Please file a bug report. https://issues.dlang.org -Steve It works with LDC2 for you? I'm having the latest version (ldc 1.28.0) downloaded from the [release](https://github.com/ldc-developers/ldc/releases/tag/v1.28.0) page for Linux (X86_64) and it doesn't seem to work for me. These 2 errors are not present with LDC2 however, I'm now getting some other errors with LDC2. How was your LDC2 built? Also it is worth noting that the compiler that is used to preprocess the file will result in different error messages when trying to use ImportC. For example when using cproc to preprocess and then LDC2 to compile, the error message is the following: ``` toml.c(638): Error: assignment cannot be used as a condition, perhaps `==` was meant? toml.c(671): Error: assignment cannot be used as a condition, perhaps `==` was meant? toml.c(1027): Error: assignment cannot be used as a condition, perhaps `==` was meant? toml.c(1140): Error: assignment cannot be used as a condition, perhaps `==` was meant? toml.c(1844): Error: cannot implicitly convert expression `*((*tab).arr + cast(long)i * 8L)` of type `const(toml_array_t*)` to `toml_array_t*` toml.c(1855): Error: cannot implicitly convert expression `*((*tab).tab + cast(long)i * 8L)` of type `const(toml_table_t*)` to `toml_table_t*` toml.c(1914): Error: cannot implicitly convert expression `0 <= idx && (idx < (*arr).nitem) ? (*((*arr).item + cast(long)idx * 32L)).arr : cast(const(toml_array_t*))0LU` of type `const(toml_array_t*)` to `toml_array_t*` toml.c(1919): Error: cannot implicitly convert expression `0 <= idx && (idx < (*arr).nitem) ? (*((*arr).item + cast(long)idx * 32L)).tab : cast(const(toml_table_t*))0LU` of type `const(toml_table_t*)` to `toml_table_t*` toml.c(2247): Error: assignment cannot be used as a condition, perhaps `==` was meant? toml.c(2305): Error: assignment cannot be used as a condition, perhaps `==` was meant? ``` When preprocessing with GCC, both DMD and LDC give the same error message and it the same I've got from another time I tried to use ImportC and it is [here](https://forum.dlang.org/post/sacokknyeqqsayxou...@forum.dlang.org). Clang has the same behavior as well. When preprocessing with TCC, again both of them have the same error message and it's the following: ``` /usr/include/stdio.h(407): Error: missing comma /usr/include/stdio.h(407): Error: `=`, `;` or `,` expected /usr/include/stdio.h(410): Error: missing comma /usr/include/stdio.h(410): Error: `=`, `;` or `,` expected /usr/include/stdio.h(412): Error: missing comma /usr/include/stdio.h(412): Error: `=`, `;` or `,` expected /usr/include/stdio.h(451): Error: missing comma /usr/include/stdio.h(451): Error: `=`, `;` or `,` expected /usr/include/stdio.h(456): Error: missing comma /usr/include/stdio.h(456): Error: `=`, `;` or `,` expected /usr/include/stdio.h(459): Error: missing comma /usr/include/stdio.h(459): Error: `=`, `;` or `,` expected /usr/include/string.h(410): Error: missing comma /usr/include/string.h(410): Error: `=`, `;` or `,` expected ``` I haven't tried to preprocess with any other compilers but I don't expect anything else to work if these didn't...
Re: Completing C code with D style
On Wednesday, 10 November 2021 at 04:54:58 UTC, Stanislav Blinov wrote: On Tuesday, 9 November 2021 at 11:03:09 UTC, forkit wrote: They both produce exactly the same output. But do vastly different things. But I tell ya.. the cognitive load .. well.. it increased dramatically ;-) Of course it did. Cuz you overthunk it. Dramatically. Your D version allocates memory, for no good reason. I mean, to store results, but you already have storage for them, so kinda pointless. Your C version, OTOH, stores results on stack (so again, why did you allocate for them in D?..), but allocates some "string builder" for... what, exactly? The program is filter, or sort + partition. Requires 0 allocations in C or D. And.. in any case, the take away from this thread should not be about nonallocating coding, but rather the interesting comment from the originl op.. "Wow! your code seem so nice, I like it although I don't know how exactly it works."
Re: Completing C code with D style
On Wednesday, 10 November 2021 at 04:54:58 UTC, Stanislav Blinov wrote: On Tuesday, 9 November 2021 at 11:03:09 UTC, forkit wrote: They both produce exactly the same output. But do vastly different things. But I tell ya.. the cognitive load .. well.. it increased dramatically ;-) Of course it did. Cuz you overthunk it. Dramatically. Your D version allocates memory, for no good reason. I mean, to store results, but you already have storage for them, so kinda pointless. Your C version, OTOH, stores results on stack (so again, why did you allocate for them in D?..), but allocates some "string builder" for... what, exactly? The program is filter, or sort + partition. Requires 0 allocations in C or D. Thanks for your feedback. This was not production code. It took a few minutes to do it on my pc, just for a little fun. So I doubt that I 'overthunk it' in such a small amount of time ;-) Also, my thought process began from the basis that the number data was immutable, and that the final data need to be stored, so that it could be manipulated etc... at will. I also wanted the use to a message, as to what they chose (hence the manipulation of memory for a message that could not be know in advance of the user making those choices). btw. My pc has 24GB of main memory, and my CPU 8MB L3 cache. So I really don't give a damn about allocations .. not one little bit ;-) Now if I were running a million processes across 1000's of servers, I probably would give a damn.
Re: Cannot compile C file using ImportC
On Wednesday, 10 November 2021 at 06:38:58 UTC, rempas wrote: On Tuesday, 9 November 2021 at 22:19:37 UTC, Stefan Koch wrote: It rather tries to interpret the C code as D code. It's not a full C compiler rather it's a shim in front of the D frontend. Therefore bugs like the above can happen if the compiler wasn't aware that the function identifier was to be interpreted in "C context" I also think that Stefan is right here. If we check the spec page for [ImportC](https://dlang.org/spec/importc.html), in the 2nd note, first sentence, it says: "ImportC is a C compiler embedded into the D implementation". To me that seems that it is a full C compiler that treats the syntax as C and creates files that can be linked with D. *I also think that "STEVEN" is right. Sorry, mistakes happen...
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 22:19:37 UTC, Stefan Koch wrote: It rather tries to interpret the C code as D code. It's not a full C compiler rather it's a shim in front of the D frontend. Therefore bugs like the above can happen if the compiler wasn't aware that the function identifier was to be interpreted in "C context" I also think that Stefan is right here. If we check the spec page for [ImportC](https://dlang.org/spec/importc.html), in the 2nd note, first sentence, it says: "ImportC is a C compiler embedded into the D implementation". To me that seems that it is a full C compiler that treats the syntax as C and creates files that can be linked with D.
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 19:34:44 UTC, Stefan Koch wrote: What's happening here is that dmd seems to see `free` as function rather than a pointer to a function. changing `static void* (*ppmalloc)(size_t) = malloc;` to `static void* (*ppmalloc)(size_t) = ` may solve your issue. Thanks for the answer but this seems to create even more bugs
Re: Completing C code with D style
On Tuesday, 9 November 2021 at 11:03:09 UTC, forkit wrote: They both produce exactly the same output. But do vastly different things. But I tell ya.. the cognitive load .. well.. it increased dramatically ;-) Of course it did. Cuz you overthunk it. Dramatically. Your D version allocates memory, for no good reason. I mean, to store results, but you already have storage for them, so kinda pointless. Your C version, OTOH, stores results on stack (so again, why did you allocate for them in D?..), but allocates some "string builder" for... what, exactly? The program is filter, or sort + partition. Requires 0 allocations in C or D.
Re: Cannot compile C file using ImportC
On 11/9/21 5:19 PM, Stefan Koch wrote: On Tuesday, 9 November 2021 at 21:03:20 UTC, Steven Schveighoffer wrote: On 11/9/21 3:05 PM, Stefan Koch wrote: Yes it is valid C. It is not valid D though. The file is named `tomld.c` The way importC works is, you pass a .c file to the compiler, and it treats it as C. It rather tries to interpret the C code as D code. It's not a full C compiler rather it's a shim in front of the D frontend. Therefore bugs like the above can happen if the compiler wasn't aware that the function identifier was to be interpreted in "C context" I'm not sure where this conversation is going. ImportC is supposed to compile C files. Any case where it doesn't compile C files (at least standards-conforming ones) is a bug. -Steve
Re: dmd 2.098.0: version `GLIBC_2.14' not found (required by linux/bin64/dmd)
On Tuesday, 9 November 2021 at 00:22:35 UTC, jfondren wrote: On Monday, 8 November 2021 at 23:55:02 UTC, kdevel wrote: In previous versions I used the linux32/dmd with the -m64 switch in order to generate 64-bit code. But this does not work anymore: $ linux/bin32/dmd linux/bin32/dmd: /lib/libc.so.6: version `GLIBC_2.28' not found (required by linux/bin32/dmd) dmd version v2.089.0 should work for you, 2.098.0 in 64 Bit works for me as well. I used patchelf to change the dynamic loader and the rpath to use a local build of a more modern glibc. [...] Is it possible to build the compiler and the tools with more "backward compatible" glibc version numers like memcpy@GLIBC_2.2.5 and fcntl@GLIBC_2.2.5? IIRC this is accomplished by using asm (".symver memcpy, memcpy@GLIBC_2.2.5"); asm (".symver fcntl, fcntl@GLIBC_2.2.5"); in the source code. ... I'd hope that the version numbers aren't so meaningless that dmd could get away with just lying about them and not have horrible problems. I'd prefer that dmd work out of the box on old Linux systems too, but you're probably past EOL in other big ways as well, there. A stock CentOS6 system comes with a root privilege escalation vuln in sudoedit I am the only user on my machine and know the root password. In environments with multiple non-root-users setuid-programs like sudo are usually not executable by untrusted users. If you take a look at SUSE's products [1] you will find that SUSE Linux Enterprise Server 11 long term support ends as late as on 31 Mar 2022. Its glibc is based on GNU glibc 2.11.3. [1] https://www.suse.com/de-de/lifecycle/
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 21:03:20 UTC, Steven Schveighoffer wrote: On 11/9/21 3:05 PM, Stefan Koch wrote: Yes it is valid C. It is not valid D though. The file is named `tomld.c` The way importC works is, you pass a .c file to the compiler, and it treats it as C. -Steve It rather tries to interpret the C code as D code. It's not a full C compiler rather it's a shim in front of the D frontend. Therefore bugs like the above can happen if the compiler wasn't aware that the function identifier was to be interpreted in "C context"
Re: Cannot compile C file using ImportC
On 11/9/21 3:05 PM, Stefan Koch wrote: Yes it is valid C. It is not valid D though. The file is named `tomld.c` The way importC works is, you pass a .c file to the compiler, and it treats it as C. -Steve
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 19:53:48 UTC, Steven Schveighoffer wrote: On 11/9/21 2:34 PM, Stefan Koch wrote: On Tuesday, 9 November 2021 at 11:45:28 UTC, rempas wrote: [...] What's happening here is that dmd seems to see `free` as function rather than a pointer to a function. changing `static void* (*ppmalloc)(size_t) = malloc;` to `static void* (*ppmalloc)(size_t) = ` may solve your issue. No, the original is valid C, you don't need the address operator. It's telling that in ldc2 1.28.0, with the new importC feature, it builds fine. It also builds fine with gcc. -Steve Yes it is valid C. It is not valid D though.
Re: Cannot compile C file using ImportC
On 11/9/21 2:34 PM, Stefan Koch wrote: On Tuesday, 9 November 2021 at 11:45:28 UTC, rempas wrote: ``` toml.c(39): Error: cannot implicitly convert expression `malloc` of type `extern (C) void*(ulong __size)` to `extern (C) void* function(ulong)` toml.c(40): Error: cannot implicitly convert expression `free` of type `extern (C) void(void* __ptr)` to `extern (C) void function(void*)` ``` What's happening here is that dmd seems to see `free` as function rather than a pointer to a function. changing `static void* (*ppmalloc)(size_t) = malloc;` to `static void* (*ppmalloc)(size_t) = ` may solve your issue. No, the original is valid C, you don't need the address operator. It's telling that in ldc2 1.28.0, with the new importC feature, it builds fine. It also builds fine with gcc. -Steve
Re: Cannot compile C file using ImportC
On Tuesday, 9 November 2021 at 11:45:28 UTC, rempas wrote: ``` toml.c(39): Error: cannot implicitly convert expression `malloc` of type `extern (C) void*(ulong __size)` to `extern (C) void* function(ulong)` toml.c(40): Error: cannot implicitly convert expression `free` of type `extern (C) void(void* __ptr)` to `extern (C) void function(void*)` ``` What's happening here is that dmd seems to see `free` as function rather than a pointer to a function. changing `static void* (*ppmalloc)(size_t) = malloc;` to `static void* (*ppmalloc)(size_t) = ` may solve your issue.
Re: auto ref function parameter causes that non copyable struct is copied?
On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote: Bug or feature? :) I've reported it in https://issues.dlang.org/show_bug.cgi?id=22498.
Knowledge is power
Just putting this excellent collection of D idioms here for those new to the language: https://p0nce.github.io/d-idioms/
Re: Cannot compile C file using ImportC
On 11/9/21 6:45 AM, rempas wrote: So I'm trying to compile the [toml99](https://github.com/cktan/tomlc99) C library with DMD using ImportC. I first preprocessed the file using `cproc`. The reason I didn't used GCC is because it defines some symbols specific to GCC so it will furthermore mess the compilation process. I created a gist of the file and uploaded [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63) in case someone wants to get the file and try it. The error message I'm getting is the following: ``` toml.c(39): Error: cannot implicitly convert expression `malloc` of type `extern (C) void*(ulong __size)` to `extern (C) void* function(ulong)` toml.c(40): Error: cannot implicitly convert expression `free` of type `extern (C) void(void* __ptr)` to `extern (C) void function(void*)` ``` These two symbols are function pointers but I wasn't able to modify and make it work. Any ideas? It seems like it should work. Figuring out the "lines" for things is really difficult in this expanded format, even though I know why it does that. I think importC should possibly allow printing of the actual source line along with the explicit source file/line, because knowing the vagrancies of the preprocessor is not going to be something that's easy to deal with, and you want to see what raw format is being passed to the compiler. [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63#file-tomld-c-L1439) is where "line 39" of toml.c is. [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63#file-tomld-c-L763) is where the definition of `malloc` is. To me, this looks reasonable. I narrowed it down to the following file, and it builds with gcc and ldc2 on my system. I don't have support for DMD, as this is an Arm system, but on another system, I can confirm that DMD 2.098.0 does not compile this: ```c typedef long unsigned int size_t; extern void *malloc (size_t __size) ; static void* (*ppmalloc)(size_t) = malloc; ``` I used `dmd -c testc.c`, `gcc -c testc.c` and `ldc2 -c testc.c`. Please file a bug report. https://issues.dlang.org -Steve
Re: Can we do system calls like that in D?
On Tuesday, 9 November 2021 at 11:52:10 UTC, rempas wrote: It's an attribute. I'm talking specifically about the `@extern(syscall, )` attribute that let's you make an system call and bind it under a name without having any library linked or without having to write any assembly. Is this possible in D? I'd be very easy to do that as a library mixin. You'd write @syscall(45) void whatever(); mixin BindSyscalls; and then the library generates the bodies as inline asm.
Can we do system calls like that in D?
There is an amazing feature in a language that is is in alpha called [vox](https://github.com/MrSmith33/vox). Vox is actually inspired from the D language. This feature is described [here](https://github.com/MrSmith33/vox/blob/master/spec/index.md#built-in-attributes) and It's an attribute. I'm talking specifically about the `@extern(syscall, )` attribute that let's you make an system call and bind it under a name without having any library linked or without having to write any assembly. Is this possible in D?
Cannot compile C file using ImportC
So I'm trying to compile the [toml99](https://github.com/cktan/tomlc99) C library with DMD using ImportC. I first preprocessed the file using `cproc`. The reason I didn't used GCC is because it defines some symbols specific to GCC so it will furthermore mess the compilation process. I created a gist of the file and uploaded [here](https://gist.github.com/rempas/a1633ba4d3fd4f166277d7ff35cedc63) in case someone wants to get the file and try it. The error message I'm getting is the following: ``` toml.c(39): Error: cannot implicitly convert expression `malloc` of type `extern (C) void*(ulong __size)` to `extern (C) void* function(ulong)` toml.c(40): Error: cannot implicitly convert expression `free` of type `extern (C) void(void* __ptr)` to `extern (C) void function(void*)` ``` These two symbols are function pointers but I wasn't able to modify and make it work. Any ideas?
Re: Completing C code with D style
On Monday, 8 November 2021 at 12:04:26 UTC, forkit wrote: On Tuesday, 2 November 2021 at 23:45:39 UTC, pascal111 wrote: Next code originally was a classic C code I've written, it's pure vertical thinking, now, I converted it successfully to D code, but I think I made no much changes to make it has more horizontal thinking style that it seems D programmers care in horizontal thinking style. Is there any additions I can make in the code to make it suitable with D style or it's fine? Oh man! some of those answers... whoohah Here's mine, with a little of that horizontal thinking ;-) And just had a little fun transposing my D code back into C. They both produce exactly the same output. But I tell ya.. the cognitive load .. well.. it increased dramatically ;-) increased cognitive load bad! // == #include #include #include #include #include void displayResults(const char answer1, const char answer2); int main(void) { char answer1, answer2; while (true) { printf("Would you like in list (n=negatives, p=positives, b=both)? "); scanf_s(" %c", , 1); if (answer1 == 'n' || answer1 == 'p' || answer1 == 'b') { break; } printf("%c is not a valid answer. Try again.\n", answer1); } while (true) { printf("Would you like in list (e=evens, o=odds, b=both)? "); scanf_s(" %c", , 1); if (answer2 == 'e' || answer2 == 'o' || answer2 == 'b') { break; } printf("%c is not a valid answer. Try again.\n", answer2); } displayResults(answer1, answer2); putchar('\n'); return EXIT_SUCCESS; } void displayResults(const char answer1, const char answer2) { // NOTE: 0 is neither positive or negative, but is considered to be even int numbers[11] = {-3, 14, 47, -49, -30, 15, 4, -82, 99, 26, 0}; // an array to store results from answer1 int result1[sizeof(numbers) / sizeof(numbers[0])]; // the final array that consolidates the results from answer1 and answer2 // must be at least this size in case it stores all elements from numbers. int finalResult[sizeof(numbers) / sizeof(numbers[0])]; int result1Count = 0; // to keep count of number of elements aquired in answer1 int result2Count = 0; // to keep count of number of elements aquired in answer2 // my version of a string builder ;-) const int msgSize = 50; // should be large enough to hold the entire message. char *const resultMsg = (char *)malloc(msgSize); if (resultMsg == NULL) { exit(EXIT_FAILURE); // not enough memory!! really??!! } strcpy_s(resultMsg, 15, "\nHere are all "); switch (answer1) { case 'n': for (size_t i = 0; i < sizeof(numbers) / sizeof(int); i++) { if (numbers[i] < 0) result1[result1Count++] = numbers[i]; } memcpy((char *)resultMsg + 14, "[negative] \0", 12); break; case 'p': for (size_t i = 0; i < sizeof(numbers) / sizeof(int); i++) { if (numbers[i] > 0) result1[result1Count++] = numbers[i]; } memcpy((char *)resultMsg + 14, "[positive] \0", 12); break; case 'b': for (size_t i = 0; i < sizeof(numbers) / sizeof(int); i++) { result1[result1Count++] = numbers[i]; } break; default: // how could it ever get here?? printf("Bad input!!\n%c is not a valid answer.", answer1); assert(0); // don't waste my time! } // debug /* { printf("\n[ result1Count after processing answer1 is: %d ]\n ", result1Count); for (int i = 0; i < result1Count; i++) { printf("%d ", result1[i]); } putchar('\n'); } */ switch (answer2) { case 'e': for (int i = 0; i < result1Count; i++) { if ((result1[i] % 2) == 0) finalResult[result2Count++] = result1[i]; } if (answer1 == 'b') { memcpy((char *)resultMsg + 14, "[even]\0", 7); } else { memcpy((char *)resultMsg + 25, "[even]\0", 7); } break; case 'o': for (int i = 0; i < result1Count; i++) { if ((result1[i] % 2) != 0) finalResult[result2Count++] = result1[i]; } if (answer1 == 'b') { memcpy((char *)resultMsg + 14, "[odd]\0", 6); } else { memcpy((char *)resultMsg + 25, "[odd]\0", 6); } break; case 'b': for (int