You could create this as a frontend macro preprocessor that implements new language constructs. Maybe it could be called cfront. I just hope that the usefulness of that doesn't lead to bloated and complex codebases and binaries as features are added to the preprocessor.
There are several reasons why not to resort to third-party code generators [1]. This includes the burden of maintenance (think about the build process) and seamless integration of native macros with other code. Do you have some code to show bloated binaries with Datatype99/Interface99? The last time I checked the generated assembly code, it was nearly of the same size as hand-written code [2]. [1]: https://github.com…
Macros on Steroids: How pure C can benefit from metaprogramming
31–40 of 63 posts
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#32Never had such a nightmare.
For metaprogramming C you should use real macros like Lisp. We have been doing that for a long time.
Using the C preprocesor is a terrible idea. With the preprocessor you could create code, but a professional environment requires things like being able to go backwards, not just from Macro source code to executable but from the executable to source code.
What do I mean with that?
In a professional environment, when something happens, for example your program goes too slow for a customer you need to understand what is happening as fast as possible. C MACROS and preprocessor are evil for that.
The c preprocessor replaces something by something else and the process is completely opaque. If you have multiple layers of macros, codes becomes impossible to follow, isolate and understand with a debugger or a profiler.
All our code has C MACROS of any type forbidden, only permitted in external libraries. Our build process detects C Macros and stops compilation if it finds them.
Usually the way things work someone creates a easy C macro to automate some small thing, then a month later someone else creates another macro that uses the macro in a two layer system, then someone else creates another macro over the macros and leaves the old macros there.
That makes code extremely hard to understand, isolate, modularize, trace or debug. C programmers could have the temptation not to learn different tools for metaprogramming. We don't let you do that, if you want to do metaprogramming you are forced to learn the proper tools for the job.
That has made our codebase extremely robust. We use real metaprogramming with our own tools, not hacks, and that gives us a tremendous competitive advantage because problems takes 1/10th or 1/100th the time for being solved.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#33>Have you ever envisioned the daily C preprocessor as a tool for some decent metaprogramming? Never had such a nightmare. For metaprogramming C you should use real macros like Lisp. We have been doing that for a long time. Using the C preprocesor is a terrible idea. With the preprocessor you could create code, but a professional environment requires things like being able to go backwards, not just from Macro source c…
It's not true for Datatype99 & Interface99. Their code generation semantics are completely transparent to a user of these macros [1] [2].
> That has made our codebase extremely robust. We use real metaprogramming with our own tools, not hacks, and that gives us a tremendous competitive advantage because problems takes 1/10th or 1/100th the time for being solved.
If you use third-party tools and you're okay with that, I'm not saying you should stop using them, I'm saying that there is another solution with advantages over third-party tools [3].
If native macros haven't worked for your codebase, it doesn't mean they don't work for others. I would not say that the preprocessor is a thing to always avoid -- there are many examples why it is helpful, and even more helpful than any kind of third-party tools you can come up with.
> Usually the way things work someone creates a easy C macro to automate some small thing, then a month later someone else creates another macro that uses the macro in a two layer system, then someone else creates another macro over the macros and leaves the old macros there.
How third-party tools are different from native macros in this case?
[1]: https://github.com/Hirrolot/datatype99#semantics [2]: https://github.com/Hirrolot/interface99#semantics [3]: https://github.com/Hirrolot/metalang99#q-why-not-third-party...
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#34The traditional way to do any kind of meaningful metaprogramming in C is just a printf() to a .h or .c file which then is included to your build.
There are a lot of projects doing that. Bison is supposed to be used this way, other projects are doing build configuration like that - by emitting a header with a ton of #define’s, and there’s a ton of languages which use C as a compilation target - and you can see what they are doing and get inspiration from that.
In my opinion it’s an extremely powerful model, much better than anything you can do with the preprocessor.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#35Something about macros that I don't see discussed much is the trade-off between improved clarity of intent vs learning curve for contributors. I don't have a ton of experience w/ C, but the large projects I've seen appear to have a tendency to avoid heavy macro usage (e.g. using `void *` for hashmap implementations instead of reaching for macros, for example). I see macros appear more frequently among those that prio…
Most of them just were not conscious of the consequences of their behavior. E.g this behavior is typical of someone that programs for a living but does not debug her own code, because someone else in the company does. So she is isolated from the consequences of her actions.
For making them understand it is as easy as making the debugger people to program and the programming people to debug for a while.
Nothing like making people miserable suffering from bad source code they have themselves created for making them understand.
Then you give them solutions for their misery and they learn pretty fast.
Experienced C programmers tend to avoid the trap of using heavy macros because they have learned. But at the same time they look for alternatives that make them more productive with some king of real metaprogramming.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#36Earlier quoted context omitted.
If you need these kinds of advanced metaprogramming capabilities then I feel like that's a sign that maybe plain C isn't suitable for your project and you'd better off switching to Zig, Rust, D or C++. These all provide powerful compile-time execution capabilities and the ability to expose C interfaces.
Even those may not be powerful enough. I have a use case where I was trying to read specification files to generate unicode tables. But using something like zig's @embedFile to get a handle to a []u8 in a comptime block doesn't work because I don't want the file to be embedded into the binary; I want something more akin to turing complete code generation. And I don't need it to run it on every compile, as the entire…
Might be nice to bring it to their attention, if you haven't already, and if you have the time and inclination.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#37The C preprocessor is definitely ill-suited for metaprogramming, but it was never the C way, was it? The traditional way to do any kind of meaningful metaprogramming in C is just a printf() to a .h or .c file which then is included to your build. There are a lot of projects doing that. Bison is supposed to be used this way, other projects are doing build configuration like that - by emitting a header with a ton of #d…
[1]: https://github.com/Hirrolot/metalang99#q-why-not-third-party...
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#38There are good reasons to reach for macro libraries. They're rare, but they're out there. I make heavy use of boost::preprocessor in a C project and it was fundamentally enabling. I have occasionally cursed at it but never regretted it. It is basically impossible to provide a "kind" development environment using deep macro trickery. The error messages you get from this kind of library are a major handicap. This faili…
> It is basically impossible to provide a "kind" development environment using deep macro trickery. Unless it's in a language actually designed for meta-programming. Obviously if you are already in a C project this might not be practical, but if you need a lot of it you may just be using the wrong tool for the job.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#39The C preprocessor is definitely ill-suited for metaprogramming, but it was never the C way, was it? The traditional way to do any kind of meaningful metaprogramming in C is just a printf() to a .h or .c file which then is included to your build. There are a lot of projects doing that. Bison is supposed to be used this way, other projects are doing build configuration like that - by emitting a header with a ton of #d…
If we are talking about such abstractions as Datatype99, this model is less convenient than native macros [1]. You have to write code in separate files, IDE support is lacking, sophisticating a build procedure, etc etc. [1]: https://github.com/Hirrolot/metalang99#q-why-not-third-party...
Compared to that, debugging generated code is a breeze.
Also, there’s no “third-party” generators - everything just lives in your own source tree. If I ever need to go meta, it’s just a printf away; I can even commit the generated files to my VCS and be able to see what had changed in them between commits in a simple and understandable diff.
Regarding the integration, I’ll take setting up an additional build phase (once) over having to debug C macros any day.
Re: Macros on Steroids: How pure C can benefit from metaprogramming
#40Earlier quoted context omitted.
If we are talking about such abstractions as Datatype99, this model is less convenient than native macros [1]. You have to write code in separate files, IDE support is lacking, sophisticating a build procedure, etc etc. [1]: https://github.com/Hirrolot/metalang99#q-why-not-third-party...
Native macros were never supposed to be used that way. If anything goes wrong, you still have to deal with that, and no IDE will save you from having to invoke your compiler with “preprocess-only” flag to see what you’re dealing with. Been there, done that, don’t want to do that ever again. Compared to that, debugging generated code is a breeze. Also, there’s no “third-party” generators - everything just lives in you…
~95% of errors from Datatype99 can be observed from the console, I hardly ever run my compiler with -E. What I mean by IDE support is that you invoke macros in the same files in which you write ordinary C code, you can't do that with printf. Imagine that you write your tagged unions (datatype(...)) inside separate files, it's clearly less convenient than embedded definitions.
> Regarding the integration, I’ll take setting up an additional build phase (once) over having to debug C macros any day.
I can't remember the time when I debugged already written and tested macros from Datatype99/Interface99, to be honest.