Live data from Hacker News

Cost of enum-to-string: C++26 reflection vs. the old ways

vittorioromeo.com

31–40 of 189 posts

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#31
post #19

I think the conclusion section should indicate that they are based entirely on GCC 16's behavior and current implementation. We should avoid generalizing one compiler's behavior and performance. Curious how this same test would behave once clang ships C++26 reflection.

I explicitly mentioned that GCC 16.1 was the compiler used in the benchmarking section, do you think I also need to add a disclaimer in the conclusion section as well?

Regardless, I don't think things are going to differ much with Clang. Without PCH/modules, standard header inclusion is still the "slow part" of C++ compilation, regardless of the compiler used and the standard library used (libstdc++ vs libc++). `#include` is fundamentally the same on any modern compiler.

Because the reflection feature itself seems quite fast on GCC (compared to the cost of the header), I predict the results will be similar on Clang as well.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#33
post #20
post #19

I think the conclusion section should indicate that they are based entirely on GCC 16's behavior and current implementation. We should avoid generalizing one compiler's behavior and performance. Curious how this same test would behave once clang ships C++26 reflection.

I was thinking the same thing. Modules are still not widely used, it is a reasonable guess that there are a lot of optimization opportunities left.

That is true, but on the other hand Modules were standardized more than 6 years ago.

Promises and claims have been made for longer than that on how Modules would have improved compilation times and made everyone's lives easier. In 2026, I still have to see any real evidence of that, especially when PCH + unity builds are much easier to use (except on damn Bazel, which supports neither) and deliver great results.

If after 6+ years of development Modules are still so far behind, it is fair to question if the problem is with the design/implementability of the feature itself.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#34

Earlier quoted context omitted.

It comes up pretty frequently in java. Serialization/Deserialization, adding capabilities based on type, Adding new capabilities to a type, general tuning (for example, adding a timing or logging call onto methods). Almost all the Java web frameworks are giant balls of reflection. Name a function the right way or add the right magic annotation and the framework will autowire it correctly. It's a pretty powerful tool.…

> Almost all the Java web frameworks are giant balls of reflection. Name a function the right way or add the right magic annotation and the framework will autowire it correctly. I find this to be very powerful, and also very unintuitive/undiscoverable at the same time.

Reflection is simply a syntax vinegar for duck typing.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#35

I can't imagine myself using reflection much, but maybe it will eliminate a lot of feature proposals bogging down the committee and they can focus on harder problems. It would be cool if the stated goal of C++29 was compile times.

I'd argue reflection is very much a feature for libraries. You wouldn't use it directly, but your JSON / YAML serialize is then built on top of it. So are your bindings for scripting engines like Lua.

You can already automatically serialize/deserialize arbitrarily nested structs since C++17 (using Boost.PFR). Since C++20, you can also serialize/deserialize the struct data member names automatically.

For many useful use cases, you don't need C++26 reflection at all. E.g. https://www.linkedin.com/posts/vittorioromeo_cpp-gamedev-ref...

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#36

Earlier quoted context omitted.

It comes up pretty frequently in java. Serialization/Deserialization, adding capabilities based on type, Adding new capabilities to a type, general tuning (for example, adding a timing or logging call onto methods). Almost all the Java web frameworks are giant balls of reflection. Name a function the right way or add the right magic annotation and the framework will autowire it correctly. It's a pretty powerful tool.…

> Almost all the Java web frameworks are giant balls of reflection. Name a function the right way or add the right magic annotation and the framework will autowire it correctly. I find this to be very powerful, and also very unintuitive/undiscoverable at the same time.

Initially, but it very quickly becomes discoverable once you are familiar with how things are working.

Most frameworks in Java are very similar. The ones that aren't are effectively doing what "expressjs" does in terms of setup, which is still pretty discoverable.

Most java frameworks rely on annotations rather than naming schemes which makes everything a lot easier to grok.

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#37

Earlier quoted context omitted.

I'd argue reflection is very much a feature for libraries. You wouldn't use it directly, but your JSON / YAML serialize is then built on top of it. So are your bindings for scripting engines like Lua.

Also nice for UI tooling; game tools, debuggers, etc. Pull apart a struct and display it on screen and not have to patch the UI tool every time you change the struct is pretty nice.

We have been able to automatically do this since C++17: https://www.linkedin.com/posts/vittorioromeo_cpp-gamedev-ref...

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#38
post #4

I've been wondering about debug-ability of code using reflection. X-Macros are quite annoying to step through in most debuggers, though possible. While the code in the first example is evaluated fully at compile-time, how would you approach debugging it?

Nothing that makes it straightforward. Testing via `static_assert` is a good strategy, but it's not debugging. I believe there are some ways of printing custom diagnostics during compilation, but I am not aware of any step-by-step debugging tool that runs at compile-time.

In practice, I haven't really needed to ever debug `consteval` functions -- it's quite easy to get the right behavior down thanks to `static_assert`-based testing and thanks to the fact that they do not depend on external state (simpler).

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#39
post #23
post #11

Earlier quoted context omitted.

C++ conference speakers (including keynotes) are now begging everyone to stop using enum to string in their example. While they are a simple and easy to understand example, reflection is for much more interesting problems. I can't think of any other example that I would type into a comment box or put on a slide.

Serialization is the canonical example. Being able to turn struct MyStruct { int val = 42; string name = "my name"; }; into { "val": 42, // if JSON had integers, and comments of course "name": "my name", } is incredibly powerfuly. If reflection supported attributes (i can't believe it shipped without, honestly), then you could also mark members as [[ignore]] and skip them.

You can achieve that since C++20 (or C++17 if you don't care about the member names). E.g. https://www.linkedin.com/posts/vittorioromeo_cpp-gamedev-ref...

(The link above shows ImGui generation, but the same exact logic can be applied for serialiation to JSON/YAML/whatever.)

Re: Cost of enum-to-string: C++26 reflection vs. the old ways

#40
post #27
post #23

Earlier quoted context omitted.

Serialization is the canonical example. Being able to turn struct MyStruct { int val = 42; string name = "my name"; }; into { "val": 42, // if JSON had integers, and comments of course "name": "my name", } is incredibly powerfuly. If reflection supported attributes (i can't believe it shipped without, honestly), then you could also mark members as [[ignore]] and skip them.

It is powerful, but I'm not sure it is a good idea. Other languages have it, and there is lots of experience in all the ways things go wrong in the real world. I'm inclined to say you should hand write this code because eventually you will discover something weird anyway.

I think this is a very bad take -- once you write it by hand you have to manually keep it in sync with the actual struct and ensure you made no mistakes. Reflection guarantees 1-1 future-proof mapping with the actual C++ struct, avoids boilerplate, and ensures that the serialization logic is correct.
Post reply on HN