The most insane macro in that is this monstrosity:<p><pre><code> #define __is_constant(x) \
(sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1)))
</code></pre>
If x is a compile-time constant, (void* )((long)(x) * 0l) is equivalent to NULL, otherwise it's just a regular void* . And if both sides of a ternary are pointers, the rule is:<p>If one side is NULL, the type of the ternary should be the type of the other side (int* in this case).<p>Otherwise, if one side is a void* , the type of the ternary should be void* .<p>So if x is constant, the type of the ternary is int* , and if it's not constant the type is void* . The sizeof(* ()) around it turns that into sizeof(int) or sizeof(void), and in the GNU dialect sizeof(void) is 1, which is different from sizeof(int). Whew.<p>What I want to know is what's wrong with __builtin_constant_p.
I often find it amusing how C advocates complain about the complexity of C++, and then proceed to implement the same complex functionality in even more brittle ways. Language features I have seen C developers emulate poorly in C: constepxr (here), virtual functions (with function pointers), templates (with macros), exceptions (with setjmp/longjmp).
The lesson here is that if you're designing an operating system, you should also be designing/evolving the programming language to go alongside it. The original authors of Unix did this (developing C in parallel), and so have many more obscure OSes. This could have been written simply as 'max()' with appropriate modifications to the compiler to make it do the right thing.
What exactly is the typecheck macro doing here? I get that it compares the sizes of two pointer values but I don't know why and I feel like there is some C standard nuance involved here that I don't understand. Also, is the `sizeof` used to force evaluation at compile time?
I’m surprised this is necessary at all. Wouldn’t a compiler at any reasonable optimisation level optimise __cmp_once into __cmp automatically (and then into the resulting max constant) if used with constants? Seems like very basic constant propagation.
I would like to use a language that doesn’t involve sizeof(typeof...) and template(Tmagic...) both.<p><pre><code> #include “meta.h”
@tr max(@ta a, @tb b)
if (is_comparable(ta, tb))
tr = common_base(ta, tb, optionshere...)
produce_code {...}
else
compile_error “incompatible types in $(__func__)”
</code></pre>
I can’t figure out for decades why can’t we just get all ideas from lisp and code in happiness.
For an explanation of __is_constant(), see the thread where it was suggested: <a href="https://lkml.org/lkml/2018/3/20/845" rel="nofollow">https://lkml.org/lkml/2018/3/20/845</a> (this was also indirectly linked to in the article)<p>tl;dr: If one of the expressions in a ternary operator is a null pointer constant, the result type is that of the other expression.
I’m not up to date on GCC macros, so I’m not familiar with this syntax:<p><pre><code> #define __cmp_once(x, y, op) ({ \
typeof(x) __x = (x); \
typeof(y) __y = (y); \
__cmp(__x, __y, op); })
</code></pre>
Is that a block-expression, or what?
I'm really confused by the 1s in this macro. What are they, syntactically? The second one looks like it could be being cast to the type "pointer to y" but the first one has the sizeof expression in front of it.<p><pre><code> #define __typecheck(x, y) \
(!!(sizeof((typeof(x)*)1 == (typeof(y)*)1)))</code></pre>