Home Technology Comparing reflection capabilities of C++, Zig and C3
Technology

Comparing reflection capabilities of C++, Zig and C3

Key Points

Comparing reflection capabilities of C++, Zig and C3 Comparing reflection capabilities of C++, Zig and C3 Reflection lets a program inspect and manipulate its own structure at runtime or compile time. All C++ (with its upcoming reflection support), Zig and C3 rely on compile-time reflection, so you can reason about types, enumerators, and struct members without any runtime cost. In this post I will compare how these languages approach compile-time reflection.

Comparing reflection capabilities of C++, Zig and C3 Comparing reflection capabilities of C++, Zig and C3 Reflection lets a program inspect and manipulate its own structure at runtime or compile time. All C++ (with its upcoming reflection support), Zig and C3 rely on compile-time reflection, so you can reason about types, enumerators, and struct members without any runtime cost. In this post I will compare how these languages approach compile-time reflection. What is C3? C3 is a relatively new programming language which mainly focuses on readability, performance, minimalism, and familiarity for C/C++ programmers. It doesn't have heavy runtime, garbage collection, exceptions or RAII. It also fully supports C ABI compatibility out of the box. C3 uses special syntax for compile-time execution: all variables, control-flow constructs are prefixed with $. This was done on purpose to explicitly show the reader which code runs at compile time. It uses macros for compile-time evaluation and reflection. C3 macros are designed to provide a replacement for C preprocessor macros. They extend such macros by providing compile-time evaluation using constant folding, which offers an IDE friendly, limited, compile-time execution. Let’s see all languages in action! Enum to string conversion C++: Zig: In Zig, the only solution I can think of is attaching a method to each enum you want to turn into a string, not a generic approach. I’m not a profound zig expert so you can correct me in the comments. C3: In C3 enums have special properties. For example, if you want to print enum value, it will print it in a readable form, exactly as defined in the source code. For example, this code: io::printfn(“%s”, Color.RED) will output RED, not 0. If you want to take the underlying value from an enum, you can either access .ordinal or cast it to the underlying type. You can also associate values of any type with your enumerators: Let’s proceed with reflections! Struct introspection C++: Zig: C3: Here, (1) C3 uses optional pre-conditions called 'contracts' which can help drastically with input validation. They will be executed at compile-time if it is possible, if not - at runtime. Validation with compile-time only attributes C++: Zig: Zig unfortunately doesn’t have ‘attributes’ or any substitute to attach compile-time data to struct members. C3: For this example with C3 I want to show you 2 options. In the first (1) variant we validate everything at compile-time, we can verify this easily by putting @const attribute on the macro. In the second (2) variant we’re mixing compile-time attributes with validation at runtime. In this example you can see how syntax distinction between $if and if helps to understand which code gets expanded at compile-time and which will execute at runtime. Conclusions All observed languages can do real compile-time reflection, which is great for serializers, debug printers, and generic helpers like the ones above. The tradeoff is ergonomics: C++ gets the power via verbose template machinery and splices, while C3 makes the same ideas more readable and expressive through its macro system and special syntax for compile-time execution, it's very easy to understand where code will execute at compile time and where it wouldn't. Zig in turn doesn't have macros, instead it relies on comptime functions and blocks, inline for loops and type-introspection builtins, which is also a good, modern and mostly readable approach. Personally, I've found C3 to be a very promising systems programming language that needs more attention; everybody knows about C++ and Zig is marketed very well, but C3 lacks that kind of marketing, though it can compete easily with Zig, Odin, or any other new systems programming language out there. Also it doesn't have tons of breaking changes with each minor version. It's a lot more stable than Zig (honestly, it's pretty embarrassing that Zig is still stuck on 0.1x versions after over 10 years of development), and since C3 is already on 0.8.x versions, 1.0 is very close, see the roadmap. You can search for more info about C3 on the main website. Want to discuss the language or have a question? Join official C3 server on Discord.
C++ (ORG) Zig (ORG) C3 Reflection (ORG) C3 (ORG) RAII (ORG) IDE (ORG) Color (ORG)
Originally published by Hacker News Read original →