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:
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:
- 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.
>
- 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).
>
- 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