Mixin C
Steven Schveighoffer
schveiguy at gmail.com
Thu Mar 28 02:24:34 UTC 2024
On Saturday, 23 March 2024 at 19:02:52 UTC, Paul Backus wrote:
> On Saturday, 23 March 2024 at 02:51:31 UTC, Steven
> Schveighoffer wrote:
>>
>> So the entirety of `stdio.h` is included in the body of the D
>> main function? Is that wise?
>
> In this specific example, it's overkill.
>
> In general...is there a better alternative? The C preprocessor
> is a blunt instrument, and if we want to have full support for
> it, we are going to have to live with the consequences of that
> bluntness.
My objection is to the *requirement* that you include it in the
main function. It's very different from D nested imports, as it
redefines everything inside the function.
Having to re-import *everything* everywhere you need to use a
macro is really bad.
>
> You can use a lambda:
>
> ```d
> enum PI = () {
> mixin(C) {
> #include "pidef.h"
> return PI;
> }
> }();
> ```
Ugh, still having to include the entirety of a C header inside a
function context.
>> What I'd like to see is:
>>
>> a) the C preprocessor is run on *all the mixin(C) islands of
>> the file* regardless of where they appear, whether they are in
>> templates, etc. Basically, take all the mixin(C) things and
>> concatenate them, run the result through the preprocessor, and
>> put the results back where they were. THEN run the importC
>> compiler on them. This allows a more cohesive C-like
>> experience, without having to import/define things over and
>> over.
>
> Some downsides to this approach:
>
> 1. Concatenating all of the `mixin(C)` blocks in a module for
> preprocessing violates D's scoping rules and creates a lot of
> opportunities for "spooky action at a distance."
But that's what you get with C. For instance, you can #define a
macro inside a function, and use it inside another function, as
long as it comes later in the file. It's not spooky to C
programmers. You can even #undef things or re #define them.
> 2. This would allow sharing macro definitions across `mixin(C)`
> blocks, but would *not* allow sharing declarations. You'd still
> have to `#include <stdio.h>` twice if you wanted to call
> `printf` in two different blocks, for example.
but you wouldn't have to include them inside the functions. You
get the function definitions and macros in the right place (at
module level).
> 3. In order to "put the results back where they were" the D
> compiler would have to parse the preprocessor's output for line
> markers. Since the format of these is not specified by the C
> standard, this means the D compiler would have to have separate
> parsers for each C preprocessor implementation (or, at least,
> one for gcc/clang and one for MSVC).
I came up with an approach for this, I detailed it in my dconf
talk last year. All preprocessors have a flag which preserves
comments.
But yes, you are right this is a big hacky problem to solve.
-Steve
More information about the dip.ideas
mailing list