Consider checking whether a macro argument X may be used as a void*: ((void*){ 0 } = (X)) The compound literal creates a temporary void* object, and assignment applies only permitted implicit conversions. Unlike a cast, this preserves compiler type checking. TAKEAWAY: assignment compatibility asks whether X can be assigned to an object of type T. section 16.2
Checking a pointer macro argument
A pointer-tracing macro can use ((void*){ 0 } = (X)) before passing the result to the %p format. A pointer value is accepted through the permitted conversion to void*; a non-pointer argument produces a compiler diagnostic. The earlier cast-based form, (void*)(X), can suppress these checks.
The same idea supports other macro checks:
- Use (X)+0 to require an arithmetic argument, covering integer and floating-point values. section 16.2
- Prefer assignment over a cast when the goal is compile-time validation rather than forcibly asserting a type. section 16.2


