4 ms·
The most insane macro in that is this monstrosity: #define __is_constant(x) \ (sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1))) If x
by tbodt 9y ago
The most insane macro in that is this monstrosity:
#define __is_constant(x) \
(sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1)))
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:
If one side is NULL, the type of the ternary should be the type of the other side (int* in this case).
Otherwise, if one side is a void* , the type of the ternary should be void* .
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.
What I want to know is what's wrong with __builtin_constant_p.
- LukeShu 9y ago> What I want to know is what's wrong with __builtin_constant_p. 1. __builtin_constant_p might not return a constant--it might return a magic value that says "I don't know yet, ask me again at a later optimization step". __builtin_choose_expr needs to be evaluated pretty early, so "ask again later" isn't good enough for it. https://lkml.org/lkml/2018/3/18/268 https://lkml.org/lkml/2018/3/18/268 2. It doesn't really care if it is constant in the __builtin_constant_p-sense, it cares if it has side-effects. > ({x++; 0;}) is constant in the eyes of __builtin_constant_p, but not side-effect free. https://lkml.org/lkml/2018/3/18/316 https://lkml.org/lkml/2018/3/18/316
- deleted 9y ago[deleted]
- gerdesj 9y agoI'll also drop in another link - https://lkml.org/lkml/2018/3/20/845 https://lkml.org/lkml/2018/3/20/845 that D Wheeler pointed out in LWN and this quote from Mr T's reaction: >That's not "an idea". >That is either genius, or a seriously diseased mind. >I can't quite tell which.
- halayli 9y agoIt would be nice to credit this explanation to Linus.
- anothergoogler 9y agoYea I mean isn't parent's comment just a ripoff of that entire thread?
- deleted 9y ago[deleted]
- abhishekjha 9y agoNo wonder I thought I had read this before.
- tbodt 9y agoNo, I wrote it myself. I figured out how it worked from reading the C standard.
- abhishekjha 9y agoI think the above macro works without knowing the size of void or int.
- tbodt 9y agoIt relies on sizeof(void) and sizeof(int) being different, and also on sizeof(void) being legal (it's only legal in the gcc dialect).