A type trait is a compile-time operation that queries a property of a type and produces a result representing that property. In C, typeof, typeof_unqual, and _Generic can combine to implement type-generic features. section 18.3.2
Type-directed power
A pow macro can inspect the types of X and Y with _Generic, select an integer or floating-point library function, and use typeof_unqual to cast the result to the narrowest suitable unqualified floating-point type. section 18.3.2
Type-trait macros are constrained to accept either an expression without an exposed comma or a type name and produce bool integer constant expressions.
- Use tozero and tonull to create a zero or null pointer without evaluating the argument. section 18.3.2
- Test integer types, variable-length arrays, and const- or volatile-qualified pointer targets. section 18.3.2
#define static_assert_compatible(A, B, REASON) \
static_assert(_Generic((typeof(A)*)nullptr, \
typeof(B)*: true, \
default: false), \
"expected compatible types: " REASON ", have " #A " and " #B "")
A static assertion can compare types by applying _Generic to a pointer formed from typeof(A) and matching typeof(B)*. section 18.3.2

