If I may may be provocative :-) this post isn't about C. It's about layering on a custom language using C preprocessor macros.
My compilers were originally written in C. I started using the C preprocessor to do metaprogramming. After some years I got fed up with it and removed nearly all of the preprocessor use, and never looked back. My code was much easier to understand.
An amusing story: long ago, a friend of mine working for Microsoft was told by a team leader that a 50K program had a bug in it, and sadly the developer was long gone. He'd assigned programmer after programmer to it, who could not fix it. My friend said he'd give it a try, and had it fixed in 2 hours.
The source code was written in Microsoft MASM, where the M stood for "Macro". You can guess where this is going. The developer had invented his own high level language using the macro system (which was much more powerful than C's). Unfortunately, he neglected to document it, and the other programmers spent weeks studying it and could not figure it out.
The leader, astonished, asked him how he figured it out in 2 hours? My friend said simple. He assembled it to object code, then disassembled the object code with obj2asm (a disassembler I wrote that converts object code back to source code). He then immediately found and fixed the bug, and checked in the "new" source code which was the disassembled version.
I've seen many very smart and clever uses of the C macros, the article is one of them. But isn't it time to move on?
I could tell a similar story (many, in fact) about C++'s templates. It is not entirely clear to me what exactly makes the preprocessor a bad choice. One could argue that it is too flexible, so it is possible to create a mess with it. But somehow this seems a rather weak argument for inventing another monomorphization layer, which often evolve into their own mess.
You can definitely make an incomprehensible soup out of C++ templates. C++ expression templates are a classic example. But the threshold of this is much higher than with a macro language.
Using C++ templates for a linked list type doesn't make a mess.
I am not sure, I quite like the new C macro-templates. I also do not think the implementation is messy. Can you narrow down specific aspects where you think using macros for this is problematic?
Pedantically, the preprocessor is an entirely separate language. The lexing, parsing, expressions, and semantics are totally distinct. The preprocessor is usually implemented as a completely independent program. My first C compiler did integrate the preprocessor with the C compiler, but that was for performance reasons.
Currently, ImportC runs cpp and then lexes/parses the resulting C code for use in D.
On some projects you must use C.