Mixin C
Paul Backus
snarwin at gmail.com
Sat Mar 23 19:02:52 UTC 2024
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.
With Mixin C, the D programmer at least gets to choose whether
they would rather pay the cost of `#include`-ing C headers
multiple times, or the cost of translating preprocessor macros by
hand.
> The other problem is if you want to use C expressions in D. For
> example, let's say you have the C definition:
>
> ```c
> #define PI 3.14159
> ```
>
> How can I use this in D land? I could assign it to a variable
> maybe?
>
> ```d
> mixin(C) {
> #include "pidef.h"
> double PI_ = PI;
> }
> ```
>
> Note, I have to use a new name. And it has to be a variable,
> because that's all you can do in C. What if I wanted it to be
> an enum? Too bad, C doesn't support that.
You can use a lambda:
```d
enum PI = () {
mixin(C) {
#include "pidef.h"
return PI;
}
}();
```
> 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."
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.
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][1]. 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).
[1]: https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
More information about the dip.ideas
mailing list