Live data from Hacker News

C Macro Reflection in Zig

jstrieb.github.io

1–10 of 139 posts

Re: C Macro Reflection in Zig

#4
Clang's preprocessor is actually not implemented as a separate compilation pre-pass, it's essentially a part of the lexer and I would be willing to bet that gcc uses a similar scheme.

So there is nothing technically impossible about having the access to macro names as a compiler-specific extension, it's just that there is no much demand for it.

Re: C Macro Reflection in Zig

#5
post #3

Wouldn’t this add at least UINT16_MAX*sizeof(intptr_t) bytes into the executable per enum?

I think the executable will essentially contain a lookup table with 2^16 slots and the string data for each macro name matching WM_* in Windows.h. But it's hard to come up with a better solution since the actually required names are unpredictable at compile time. The size of the lookup table could be reduced though if the WM_* values occupy a much smaller range.

Re: C Macro Reflection in Zig

#6
I really want to like zig, but I've just had some annoying problems with it, most of which I think are just a result of it not being in 1.0 yet. For example, the recommended way to start a project, with `zig init`, has a load of code that I really don't need when I just want a bare project to get started. I only recently found out that you can just `zig build-exe filename.zig` and skip the whole init part. Also I've had a lot of issues getting editor integration to work correctly. I've installed the VSCode extension but I don't seem to be getting autocomplete etc. It is quite possibly just an ID-10T problem though, so I'll probably take another look at it some weekend

Re: C Macro Reflection in Zig

#7
post #3

Wouldn’t this add at least UINT16_MAX*sizeof(intptr_t) bytes into the executable per enum?

It adds 65536 pointers to the binary. Alternative would be to use a hash map. I think if they made function that used inline for instead it would optimize to a switch. No need for a LUT.

   fn stringFromMsg(umsg: c_int) [:0]const u8 {
       @setEvalBranchQuota(1000000);
       inline for (@typeInfo(win32).Struct.decls) |field| {
           if (field.name.len >= 3 and std.mem.eql(u8, field.name[0..3], "WM_")) {
               if (umsg == @field(win32, field.name)) {
                   return field.name;
               }
           }
       }
       unreachable; // umsg is not valid, programming mistake
   }
godbolt: https://zig.godbolt.org/z/7b73aoosf

In zig-budoux, I also do comptime reflection on cImport struct to assert compile time that we won't produce broken runtime code

https://github.com/Cloudef/zig-budoux/blob/master/src/c.zig#...

Re: C Macro Reflection in Zig

#8
post #2

@cImport is on the chopping block though [0]. You will still be able to import c files but it will require a little more work. This is because they want this functionality out of the language so they can remove libclang dependency. [0]: https://github.com/ziglang/zig/issues/20630

It would actually be nice if the translate-c build system step would also allow some restricted symbol transformation (at least stripping the 'namespace prefix' from C library symbols).

For instance Odin allows to define a 'link_prefix' for C APIs which is then stripped from the imported symbols:

    @(default_calling_convention="c", link_prefix="sg_")
This causes name transformations like:

    sg_setup() => setup()
    sg_shutdown() => shutdown()
...maybe even convert from common case-conventions (like snake-, camel-, pascal- case etc...) to Zig's naming convention so that imported C interfaces don't look so alien relative to native Zig interfaces.

Re: C Macro Reflection in Zig

#9
post #2

@cImport is on the chopping block though [0]. You will still be able to import c files but it will require a little more work. This is because they want this functionality out of the language so they can remove libclang dependency. [0]: https://github.com/ziglang/zig/issues/20630

It would actually be nice if the translate-c build system step would also allow some restricted symbol transformation (at least stripping the 'namespace prefix' from C library symbols). For instance Odin allows to define a 'link_prefix' for C APIs which is then stripped from the imported symbols: @(default_calling_convention="c", link_prefix="sg_") This causes name transformations like: sg_setup() => setup() sg_shutd…

From the issue

> As a consolation prize, the TranslateC build step can be enhanced with advanced settings, such as namespace stripping and validation of existing bindings. Since changes to this don't require changing the language, it's OK if the scope & complexity increase to some extent.

Re: C Macro Reflection in Zig

#10
post #4

Clang's preprocessor is actually not implemented as a separate compilation pre-pass, it's essentially a part of the lexer and I would be willing to bet that gcc uses a similar scheme. So there is nothing technically impossible about having the access to macro names as a compiler-specific extension, it's just that there is no much demand for it.

Clang prints out things about macro instantiations on the semantic error reporting paths. That probably means it has all the macro information available already.

It's not probably reflected to the language because C++ fears reflection in general and hates macros in particular.

Post reply on HN