It is certainly not observable through the preprocessor in #if
as you imply in your question. The preprocessor knows nothing about types, only tokens and expressions that are constructed from them.
C11 has a new feature that lets you observe a particular pointer type, but not "pointerness" in general. E.g you could do something
#define IS_TOTOP(X) _Generic((X), default: 0, struct toto*: 1)
or if you'd want that the macro also works for arrays
#define IS_TOTOPA(X) _Generic((X)+0, default: 0, struct toto*: 1)
There are already some compilers around that implement this, namely clang, and for gcc and others you can already emulate that feature with some builtins, see P99.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…