Add ImportC compiler to dmd

Walter Bright newshound2 at digitalmars.com
Mon May 10 07:21:31 UTC 2021


On 5/9/2021 11:21 PM, Patrick Schluter wrote:
> As a C programmer I do use already a lot of enums and inlines, but the C 
> semantic makes it quite tricky to use.
> To use inlines in big C projects you have to guarantee that you emit the non 
> inlined version of the function in exactly one module as some linkers do not 
> like to have multiple object files with the same functions in them.

Those linkers were obsoleted in 1990 with the advent of C++ (C++ forced the 
introduction of COMDAT sections to handle that). D relies on COMDATs, too, so if 
you're stuck on such an obsolete platform, and I know C wishes to still support 
them, D won't work on it anyway.


> You also 
> want to have always at least one uninlined version of the fucnton so that it can
> be linked with modules that were compiled with -O0 or -fno-inline. Not 
> difficult, but requires some pre-processor acrobatics that can be problematic.

With COMDATs, this is not a problem.


> The issue I see is that the preprocessor is not bound by the language syntax and 
> is sometimes used in things that cannot be translated easily to a D construct.

Yup.

> I have, for example, a lot of functions that take a string and its length. For 
> string literals it is annoying to count the number of characters so I have a 
> macro to do it:
> 
> `#define SnL(array) (array),LENGTH(array)`
> 
> one will note that this fits two parameters
> 
> The LENGTH macro is also interesting it is define as
> 
> `#define LENGTH(arr)  (NUM_ELEMS(arr)-1)` ok, so far it's easy, but here comes
> NUM_ELEMS, that I have lifted from the Linux kernel
> 
>      ```
>      #ifdef __GNUC__
>      /** Array size macro. Copied the Linux Kernel version which is not portable 
> but
>          which checks that it's a real array (not a pointer) and evaluates to a
>          constant expression. This allows to use it to declare other array 
> sizes. */
>        #define NUM_ELEMS(arr) (sizeof(struct {int 
> :-!!(__builtin_types_compatible_p(typeof (arr), typeof (&0[arr])));})+sizeof 
> (arr)/sizeof 0[arr])
>      #else
>      /** A portable variant, but which doesn't check for array or pointer. */
>        #define NUM_ELEMS(arr) (sizeof (arr)/sizeof 0[arr])
>      #endif
>      ```
> 
> This is the kind of macros that are all over the place in real C code.

I know. I used to revel in this stuff. Macros that piece together syntax are a 
horror show, and a big part of why D doesn't have macros. (I eventually removed 
all this stuff from my C code and it was much nicer as a result.)

There's no way to mechanically translate this stuff to D.

However, the preprocessed code can be compiled just fine by ImportC. You just 
won't be able to use those macros in the D code. But I'm pretty sure an 
equivalent can be made by hand.

P.S. that unnamed bit field is, well, sheesh. It could be replaced with a template.



More information about the Digitalmars-d mailing list