On Sun, 17 Nov 2024 at 11:23, David Laight <David.Laight@xxxxxxxxxx> wrote: > > Since 99% will be 1,0 maybe saving the extra expansion is best anyway. > So have is_const_zero(x) and add if_const_zero(x, if_z, if_nz) later. Ok. So something like this seems to give us the relevant cases: #define __is_const_zero(x) \ _Generic(0?(void *)(long)(x):(char *)0, char *:1, void *:0) #define is_const_zero(x) __is_const_zero(!!(x)) #define is_const_true(x) __is_const_zero(!(x)) #define is_const(x) __is_const_zero(0*!(x)) and should work with all scalar expressions that I can think of (ok, technically 'void' is a scalar type and it obviously won't work with that). And should work in all contexts. It does want a comment (in addition to the comment about how NULL is special for the ternary op that makes it work): the '(long)' cast is so that there are no warnings for casting to 'void *' when it's *not* a constant zero expression, and the '!' pattern is to turn pointers and huge constants into 'int' without loss of information and without warnings. Compound types obviously will generate a warning. As they should. The above looks reasonable to me, but I didn't actually test any of it in the actual kernel build. Linus