Mixin C

Paul Backus snarwin at gmail.com
Fri Mar 8 17:54:21 UTC 2024


On Friday, 8 March 2024 at 17:06:21 UTC, Tim wrote:
> Are multiple mixin(C) blocks evaluated in the same context? 
> Symbols and macros from one mixin(C) block could then be used 
> in another mixin(C) block, like in this example:
> ```D
> mixin(C) {
> #include <stdio.h>
> };
> void main()
> {
>     mixin(C) {
>         printf("test\n");
>     }
> }
> ```
> The preprocessor call for the second block would need to know 
> all macros from the first call.

Each block is preprocessed separately, and the result of 
preprocessing is then evaluated (type-checked and compiled) in 
the context of the enclosing D scope. So, symbols are visible 
across different blocks, but preprocessor macros are not.

Your example would work, because it would expand to this:

```d
extern(C) int printf(const(char)* format, ...);
// Other definitions from stdio.h ...

void main()
{
     printf("test\n");
}
```

But this example would not work:

```d
mixin(C) {
     #include <stdio.h>
     #define info(s) printf("[info] %s\n", s);
}

void main()
{
     mixin(C) {
         info("test"); // error - undefined identifier 'info'
     }
}
```

> Can code in mixin(C) statements access local variables from D? 
> How would name conflicts be resolved when an identifier exists 
> both in the current module and a C header file? In the 
> following example `BUFSIZ` is both a local variable and a macro 
> from a C header:
> ```D
> void main()
> {
>     int BUFSIZ = 5;
>     mixin(C) {
>         #include <stdio.h>
>         printf("BUFSIZ = %d\n", BUFSIZ);
>     }
> }
> ```

Name lookup in mixin(C) blocks would follow the normal D scoping 
rules.

In this example, since BUFSIZ is a macro, it would be expanded by 
the preprocessor before the D compiler even parses the C code, 
and the value from `stdio.h` would be printed.

If BUFSIZ were a variable instead of a macro, then you would get 
a compile-time error for defining two variables with the same 
name in the same scope.

> Are variables declared in mixin(C) statements interpreted as 
> global or local variables?
> ```D
> void main()
> {
>     mixin(C) {
>         #include <stdio.h>
>         fprintf(stderr, "test\n");
>     }
> }
> ```
> The header declares variable `stderr`. If this is now a local 
> variable, because the header is included inside a function, it 
> could cause problems. Maybe this could be solved by treating C 
> variables marked with `extern` as globals.

I believe the C standard actually requires such variables to be 
treated as globals. The relevant sections are [6.2.2 Linkages of 
identifiers][1] and [6.2.4 Storage durations of objects][2]. So, 
assuming the D compiler implements the C standard correctly, this 
should Just Work.

[1]: http://port70.net/~nsz/c/c11/n1570.html#6.2.2
[2]: http://port70.net/~nsz/c/c11/n1570.html#6.2.4


More information about the dip.ideas mailing list