July 30th, 2024

C Macro Reflection in Zig – Zig Has Better C Interop Than C Itself

Zig is a developing programming language aimed at low-level systems programming, offering strong C interoperability, ease of use, and features like C macro reflection, making it a potential C replacement.

Read original articleLink Icon
CuriosityFrustrationAppreciation
C Macro Reflection in Zig – Zig Has Better C Interop Than C Itself

Zig is a developing programming language aimed at low-level and systems programming, positioned as a potential replacement for C. It boasts impressive interoperability with C, allowing for easy integration of external libraries and direct use of C header files. This capability simplifies the process of calling C functions and enhances the development experience. For instance, Zig can import Windows header files seamlessly, enabling developers to write cross-platform code that compiles on any host operating system.

A notable feature of Zig is its ability to reflect on C macros, which is not possible in C due to the separation of the preprocessor and compiler. Zig allows developers to introspect C macros, making it easier to map numeric message codes to their corresponding macro names. This is particularly useful in Windows programming, where applications rely on a message-passing model to handle events.

Zig's design philosophy emphasizes pragmatism and ease of use, facilitating a smooth learning curve for new users. The language's integration with existing C libraries provides a pathway for developers to transition from C to Zig, leveraging established software while adopting a modern programming approach. Overall, Zig's straightforward cross-compilation and robust C integration make it an appealing choice for developers looking for a more ergonomic alternative to C, while its design principles foster productivity and intuitive coding practices.

AI: What people are saying
The comments reflect a mix of opinions and insights regarding the Zig programming language and its features.
  • Concerns about the removal of `@cImport` functionality and its implications for C interoperability.
  • Users express frustrations with the current state of Zig, particularly regarding project initialization and editor integration issues.
  • Some commenters appreciate the readability of Zig's function definitions and its potential as a programming language.
  • There are comparisons made between Zig and other languages, such as D, highlighting similar features like C macro reflection.
  • General enthusiasm for Zig's development and its growing popularity in the programming community.
Link Icon 10 comments
By @skywal_l - 3 months
@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

By @WalterBright - 3 months
Example from the article:

    const win32 = @cImport({
        @cInclude("windows.h");
        @cInclude("winuser.h");
    });

    pub fn main() !void {
        _ = win32.MessageBoxA(null, "world!", "Hello", 0);
    }
Equivalent D:

    import windows, winuser;
    void main() {
        MessageBoxA(null, "world!", "Hello", 0);
    }
In essence pared it down to the essentials. The compiler figures out the rest.

Sometimes people ask for a special syntax for importing C files, but I like this simplicity so much better.

By @voidUpdate - 3 months
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
By @Joker_vD - 3 months
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.

By @Uptrenda - 3 months
Those function definitions really look amazingly readable. I've seen this done before in other languages and its usually quite horrible. Maybe Zig is worth learning? This is a killer feature.
By @david2ndaccount - 3 months
I wrote a blogpost showing how you could do a similar thing in D with ImportC.

https://www.davidpriver.com/C-macro-reflection-in-D.html

By @eska - 3 months
Wouldn’t this add at least UINT16_MAX*sizeof(intptr_t) bytes into the executable per enum?
By @classified - 3 months
Thank Apple for Reader View in Safari. If you are as incompetent in visual design as the author of that page, you should really stay away from dark mode. Your readers will thank you.
By @montyanderson - 3 months
i like your site! seems like zig is really taking off.