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