From the memory-allocation point-of-view, you're right. A pointer variable on a 64-bit architecture occupies 8 bytes, no matter what type of pointer it is.
But the C compiler needs to know more about a variable than its size. An analogy:
float typically both need 4 bytes (so why have different types???), but you surely tell the compiler which one you want because their operations behave differently.
Back to pointers: there is the
* operator for dereferencing a pointer, and the
 indexing operator for relative addressing, and both need to know the pointer type.
For a pointer declared
int *pi;, a statement like
double x = *pi / 2 will truncate the division, while with a
float x = *pf / 2 will give you a fractional result. So you surely need to tell the compiler about the pointer type, for some quite important behaviour depends on that info.
And there is pointer arithmetic, e.g. the relative addressing done with the
 operator. If we have
char *pc = 0x12340; // Compiler will complain, as types don't match!
int *pi = 0x12340;
double *pd = 0x12340;
pc will be the character (byte) you find four characters after the
0x12340 address, being at
0x12344. But you'll find
pd not at
0x12344, but at
0x12360, 32 bytes after the base address, as indexing a double pointer will count in 8-byte steps instead of single bytes. And of course this also applies to all of the pointer arithmetic including the
- operators. So, once again, you need to tell the compiler about the pointer type to allow for correct pointer arithmetic.
One important feature of the C language is that the type information is kept only in the compiler. At runtime, the
pi pointer's 8 bytes in memory don't contain the information that
pi is an
int pointer. It's the compiler that produces different machine code for operations on pointers of different types.
So, if you get a pointer with value
0x123456789ABCDEF0 and no other information, you can't tell if it's a
int or a function pointer (or whatever else). Only if your compiled code contains a "debug" attachment, you might find the info there that the
pi variable is an
int pointer, and if your
0x123456789ABCDEF0 pointer value comes from that variable, then you know that you have to look for a (4-byte?)
int starting at the address of
0x123456789ABCDEF0 if you want to see the value that
pi points to.
But such a debug attachment is by no means necessary for the program to run, it's just a courtesy for people who want to look inside.