Use the same idea where the type of the expression ?: Depends on whether the argument is a constant with a null pointer or normal void * , but it detects a type with _Generic :
#define ICE_P(x) _Generic((1? (void *) ((x)*0) : (int *) 0), int*: 1, void*: 0)
Demo on Ideone. _Generic is an addition to C11, so if you are stuck on C99 or something earlier, you will not be able to use it.
In addition, you have standard references for defining a null pointer constant and a way for null pointer constants to interact with an expression type ?: ::
An integer constant expression with a value of 0 or such an expression passed to the void * type is called a null pointer constant.
and
If both the second and third operands are pointers, and one is a constant of a null pointer, and the other is a pointer, the result type is a pointer to a type that corresponds to all type qualifiers of types that are referenced by both operands. In addition, if both operands are pointers to compatible types or to different versions of compatible types, the result type is a pointer to a suitable version of the composite type; if one operand is a null pointer constant, the result is of the type of another operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to a suitable version of void .
source share