[This is] another of the differences between typedef and #define.
Type qualifiers like const can affect a pointer variable in two (or more) different ways: either the pointer can be qualified, or the value pointed to. As question 11.9 in the C FAQ list explains, when you write
int * const p;the pointer p is qualified, but when you write
const int * p;the value pointed to is qualified.
Now, if you say
#define x int*and then
const x y;the result is exactly as if you had written
const int* y;so it is the pointed-to value that is qualified. The preprocessor always does simple textual substitutions, and these take place before the compiler performs its parsing phase.
When you say
typedef int * x;on the other hand, x is a new type, encapsulating the notion “pointer to int”. Now, when you say
const x y;it is the variable y that is qualified, just as if you'd said
const int y;