From: Vincent Mailhol > Sent: 13 November 2024 17:19 > > __builtin_constant_p() is known for not always being able to produce > constant expression [1] which led to the introduction of > __is_constexpr() [2]. Because of its dependency on > __builtin_constant_p(), statically_true() suffers from the same > issues. Chalk and cheese. Personally I don't think any of the text below is really needed. You might want the final short form - but it is a short form. OTOH the implementation is horrid. You probably want to start with this (posted a while back in a minmax patch set: diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2594553bb30b..35d5b2fa4786 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -242,6 +242,23 @@ static inline void *offset_to_ptr(const int *off) /* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +/** + * __if_constexpr - Check whether an expression is an 'integer + * constant expression' + * @expr: Expression to test, not evaluated, can be a pointer + * @if_const: return value if constant + * @if_not_const: return value if not constant + * + * The return values @if_const and @if_not_const can have different types. + * + * Relies on typeof(x ? NULL : ptr_type) being ptr_type and + * typeof(x ? (void *)y : ptr_type) being 'void *'. + */ +#define __if_constexpr(expr, if_const, if_not_const) \ + _Generic(0 ? ((void *)((long)(expr) * 0l)) : (char *)0, \ + char *: (if_const), \ + void *: (if_not_const)) + /* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument. -- Then have: #define __is_constexpr(x) __if_constexpr(x, 1, 0) #define const_true(x) __if_constexpr(x, x, 0) David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)