Why do we need to specify the type of the data whose address, a pointer will hold, if all pointers are the same. Since all pointers store addresses. Also, the amount of space a pointer will require in memory depends on whether the machine is 32-bit or 64-bit.

Suppose my pointer ptr stores the address of an int and my machine is 64-bit. So, inside of my pointer ptr, I see a 8-byte (64-bit address) say, 0x123456789ABCDEF0.

Lets suppose we have a box which is labelled as ptr and it contains this (0x123456789ABCDEF0) no which is the address of an int. Now, this address (0x123456789ABCDEF0) doesn't specify if its an address of an int or char or float or double or anything else its just an address in RAM. So how does anyone else know that the pointer points to an int if they are just told that ptr is a pointer and the address it contains is (0x123456789ABCDEF0)?

  • 3
    Well, your premise is wrong: Not all pointers are equal (though your ABI may guarantee more than the language-standard), and I'm not even talking of the distinction between data- and functions-pointers. – Deduplicator Jul 10 '18 at 16:39
  • 1
    Your first paragraph answers your third paragraph and your third paragraph answers your first paragraph. – tkausl Jul 10 '18 at 17:36
  • I mean look, ptr has, say 64-bits to store something. All it stores is a 64-bit location in memory. Now, it has no space to store any other information. So, where is the int or char or float or double part? – Ahmad Nasir Jul 10 '18 at 17:48
  • 4
    @AhmadNasir: the information is baked into the instructions of the program. See here: softwareengineering.stackexchange.com/questions/291950/… – whatsisname Jul 10 '18 at 20:57
  • 1
    @AhmadNasir There have been machines where most pointers are 32 bit, but char* and void* are 64 bit. – gnasher729 Jul 10 '18 at 22:39

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: long and 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 *pf;, 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;

Then, pc[4] will be the character (byte) you find four characters after the 0x12340 address, being at 0x12344. But you'll find pd[4] 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 + and - 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 double, an 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.

  • 1
    Good answer, but consider to add a word about pointer arithmetics, that is the other important operation (besides dereferencing) which requires knowledge of the type. – Doc Brown Jul 10 '18 at 21:02
  • @DocBrown Good suggestion. I started to mention the indexing operator (as an example of pointer arithmetic), but didn't explain more about it. – Ralf Kleberhoff Jul 10 '18 at 21:09
  • There's also the -> operator, which wouldn't work without knowing which structure it should dig into. – Blrfl Jul 10 '18 at 22:22
  • 1
    "A pointer variable on a 64 bit architecture occupies 8 bytes" - there are different architectures. The C Standard only requires that char* and void* have the same representation, all struct* have the same representation, all union*, all pointers to variants of short, all pointers to variants of int, of long, of long long. – gnasher729 Jul 10 '18 at 22:42
  • 2
    What about Itanium? It's a 64 bit architecture, but function-pointers are 128 bits (address of function, value of data base register or whatever). On some ABIs though, pointers to costants containing that are used. – Deduplicator Jul 10 '18 at 22:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.