digitalmars.D.learn - Cannot compile C file using ImportC
- rempas (17/17) Nov 09 2021 So I'm trying to compile the
- Steven Schveighoffer (26/44) Nov 09 2021 It seems like it should work. Figuring out the "lines" for things is
- rempas (61/86) Nov 09 2021 It works with LDC2 for you? I'm having the latest version (ldc
- Steven Schveighoffer (10/80) Nov 10 2021 I'm using the downloaded LDC2 for aarch64.
- rempas (10/20) Nov 10 2021 How? What's the difference in your example? How you preprocessed
- Imperatorn (3/15) Nov 10 2021 Agreed. But, it must be quite seamless. But if we could get
- rempas (4/6) Nov 10 2021 It should be able to compile medium to big libraries. Nobody
- Steven Schveighoffer (8/23) Nov 10 2021 I did none of that. My example is the lines you had problems with, and
- rempas (6/12) Nov 10 2021 Actually you are right, there are ways to do that but having a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/13) Nov 12 2021 The advantage I though of when I suggested something similar many
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/7) Nov 12 2021 Well, one advantage might be that it could be easier to do escape
- Stefan Koch (6/14) Nov 09 2021 What's happening here is that dmd seems to see `free` as function
- Steven Schveighoffer (6/22) Nov 09 2021 No, the original is valid C, you don't need the address operator.
- Stefan Koch (4/20) Nov 09 2021 Yes it is valid C.
- Steven Schveighoffer (5/9) Nov 09 2021 The file is named `tomld.c`
- Stefan Koch (8/17) Nov 09 2021 It rather tries to interpret the C code as D code.
- Steven Schveighoffer (5/23) Nov 09 2021 I'm not sure where this conversation is going. ImportC is supposed to
- rempas (7/13) Nov 09 2021 I also think that Stefan is right here. If we check the spec page
- rempas (2/16) Nov 09 2021 *I also think that "STEVEN" is right. Sorry, mistakes happen...
- rempas (2/7) Nov 09 2021 Thanks for the answer but this seems to create even more bugs
- Steven Schveighoffer (8/18) Nov 10 2021 It shouldn't.
- rempas (3/11) Nov 10 2021 Yes, this is exactly what I mean!
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?
Nov 09 2021
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/a1633ba4d3fd4f166277d7ff35cedc6 #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
Nov 09 2021
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/a1633ba4d3fd4f166277d7ff35cedc6 #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 -SteveIt 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/sacokknyeqqsayxoudop 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...
Nov 09 2021
On 11/10/21 2:04 AM, rempas wrote:On Tuesday, 9 November 2021 at 13:44:04 UTC, Steven Schveighoffer wrote:I'm using the downloaded LDC2 for aarch64. But I'm not building tomld.c that you created, I'm building the reduced example (that I posted).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/a1633ba4d3fd4f166277d7ff35cedc6 #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.orgIt 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? ```That is an interesting situation -- you have D errors being applied to C code. I think those should be disabled, otherwise, you will have to change all your C code, and it's more like portC than importC. I'd suggest filing all these as issues. If importC is to be successful it has to build existing C projects. -Steve
Nov 10 2021
On Wednesday, 10 November 2021 at 15:04:35 UTC, Steven Schveighoffer wrote:I'm using the downloaded LDC2 for aarch64. But I'm not building tomld.c that you created, I'm building the reduced example (that I posted).How? What's the difference in your example? How you preprocessed and compiled?That is an interesting situation -- you have D errors being applied to C code. I think those should be disabled, otherwise, you will have to change all your C code, and it's more like portC than importC. I'd suggest filing all these as issues. If importC is to be successful it has to build existing C projects. -SteveI did! I personally believe that ImportC is the last and only chance for D. More and more people seem to abandon D libraries so more people leave and less people are coming because of that. At the same time because there are not a lot of people, there are not a lot of libraries and more get abandoned. It's actually a cycle. ImportC can be a true game changer!!!
Nov 10 2021
On Wednesday, 10 November 2021 at 17:38:12 UTC, rempas wrote:On Wednesday, 10 November 2021 at 15:04:35 UTC, Steven Schveighoffer wrote:Agreed. But, it must be quite seamless. But if we could get there, yes 🌟[...]How? What's the difference in your example? How you preprocessed and compiled?[...]I did! I personally believe that ImportC is the last and only chance for D. More and more people seem to abandon D libraries so more people leave and less people are coming because of that. At the same time because there are not a lot of people, there are not a lot of libraries and more get abandoned. It's actually a cycle. ImportC can be a true game changer!!!
Nov 10 2021
On Wednesday, 10 November 2021 at 17:57:50 UTC, Imperatorn wrote:Agreed. But, it must be quite seamless. But if we could get there, yes 🌟It should be able to compile medium to big libraries. Nobody excepts it to be able to compile GIMP but it should be a able to tomlc99 which is a little bit more than 2k lines of code
Nov 10 2021
On 11/10/21 12:38 PM, rempas wrote:On Wednesday, 10 November 2021 at 15:04:35 UTC, Steven Schveighoffer wrote:I did none of that. My example is the lines you had problems with, and only enough to make that error show up. It's just those 3 lines.I'm using the downloaded LDC2 for aarch64. But I'm not building tomld.c that you created, I'm building the reduced example (that I posted).How? What's the difference in your example? How you preprocessed and compiled?I did! I personally believe that ImportC is the last and only chance for D. More and more people seem to abandon D libraries so more people leave and less people are coming because of that. At the same time because there are not a lot of people, there are not a lot of libraries and more get abandoned. It's actually a cycle. ImportC can be a true game changer!!!I don't think ImportC is that much of a game changer (you can already make C bindings with quite a small effort, and there are tools to get you 90% there), but a broken/not working ImportC will be a huge drawback to the language, so it's important to get it right. -Steve
Nov 10 2021
On Thursday, 11 November 2021 at 02:03:22 UTC, Steven Schveighoffer wrote:I don't think ImportC is that much of a game changer (you can already make C bindings with quite a small effort, and there are tools to get you 90% there), but a broken/not working ImportC will be a huge drawback to the language, so it's important to get it right. -SteveActually you are right, there are ways to do that but having a FULLY working C compiler that will be able to do ALL the work for you will be awesome! But maybe yeah you are right, it will probably not be a game changer
Nov 10 2021
On Thursday, 11 November 2021 at 02:03:22 UTC, Steven Schveighoffer wrote:I don't think ImportC is that much of a game changer (you can already make C bindings with quite a small effort, and there are tools to get you 90% there), but a broken/not working ImportC will be a huge drawback to the language, so it's important to get it right.The advantage I though of when I suggested something similar many years ago was that it would enable inlining of C functions, but since then LLVM has gotten whole program optimization over the IR, so now the advantage is more limited. Maybe there are some metaprogramming advantages, but I cannot think of any.
Nov 12 2021
On Friday, 12 November 2021 at 08:12:22 UTC, Ola Fosheim Grøstad wrote:Maybe there are some metaprogramming advantages, but I cannot think of any.Well, one advantage might be that it could be easier to do escape analysis of C code. Not really sure if there is a difference compared to doing it over the IR, though.
Nov 12 2021
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) = &malloc;` may solve your issue.
Nov 09 2021
On 11/9/21 2:34 PM, Stefan Koch wrote:On Tuesday, 9 November 2021 at 11:45:28 UTC, rempas wrote: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``` 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) = &malloc;` may solve your issue.
Nov 09 2021
On Tuesday, 9 November 2021 at 19:53:48 UTC, Steven Schveighoffer wrote:On 11/9/21 2:34 PM, Stefan Koch wrote:Yes it is valid C. It is not valid D though.On Tuesday, 9 November 2021 at 11:45:28 UTC, rempas wrote: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[...]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) = &malloc;` may solve your issue.
Nov 09 2021
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
Nov 09 2021
On Tuesday, 9 November 2021 at 21:03:20 UTC, Steven Schveighoffer wrote:On 11/9/21 3:05 PM, 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"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
Nov 09 2021
On 11/9/21 5:19 PM, Stefan Koch wrote:On Tuesday, 9 November 2021 at 21:03:20 UTC, Steven Schveighoffer wrote: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. -SteveOn 11/9/21 3:05 PM, 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"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.
Nov 09 2021
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.
Nov 09 2021
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:*I also think that "STEVEN" is right. Sorry, mistakes happen...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.
Nov 09 2021
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) = &malloc;` may solve your issue.Thanks for the answer but this seems to create even more bugs
Nov 09 2021
On 11/10/21 1:31 AM, rempas wrote:On Tuesday, 9 November 2021 at 19:34:44 UTC, Stefan Koch wrote:It shouldn't. Perhaps you mean that you get more errors if you fix that situation? A compiler typically has phases where it can error out. This means that it might not get to further errors (or further errors are happening because of prior errors). It doesn't mean the later errors aren't there, it's just that the compiler gives up before finding them. -SteveWhat'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) = &malloc;` may solve your issue.Thanks for the answer but this seems to create even more bugs
Nov 10 2021
On Wednesday, 10 November 2021 at 15:06:26 UTC, Steven Schveighoffer wrote:It shouldn't. Perhaps you mean that you get more errors if you fix that situation? A compiler typically has phases where it can error out. This means that it might not get to further errors (or further errors are happening because of prior errors). It doesn't mean the later errors aren't there, it's just that the compiler gives up before finding them. -SteveYes, this is exactly what I mean!
Nov 10 2021