On Tue, Mar 4, 2025 at 8:51 PM Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> wrote: > > +#define __scalar_type_to_expr_cases(type) \ > + unsigned type : (unsigned type)0, signed type : (signed type)0 > +/* > + * This is lifted from __unqual_scalar_typeof in the kernel (which is used to > + * lose const qualifier etc.), but adapted to also cover pointers. It is > + * necessary because we ascertain type to create local variables in macros > + * below, but for pointers with __arena tag, we'll ascertain the underlying type > + * with the tag, causing a compilation error (as local variables that are not > + * pointers may not have __arena tag). This trick allows losing the qualifier > + * when necessary. > + */ > +#define __unqual_typeof(x) \ > + typeof(_Generic((x), \ > + char: (char)0, \ > + __scalar_type_to_expr_cases(char), \ > + __scalar_type_to_expr_cases(short), \ > + __scalar_type_to_expr_cases(int), \ > + __scalar_type_to_expr_cases(long), \ > + __scalar_type_to_expr_cases(long long), \ > + default: (typeof(x))0)) I think this needs a bigger comment to explain the nuances. btw __unqual_scalar_typeof() is using here: default: (x))) that should work to keep __arena tag, right ? Otherwise I'm lost why typeof((typeof(x))0))) is necessary. What was the idea to call it __unqual_typeof instead of sticking with the original __unqual_scalar_typeof name that preserves pointer qualifiers ?