While processors often have different instructions for "load a byte from an address", "load a 16-bit halfword from an address", and "load a 32-bit word from an address", and likewise for "store" operations, C uses the same syntax to load a byte from an address as to load any other size value. Given the statement:
int n = *p;
the compiler may generate code which loads a byte, halfword, or word from the address in p and store it into n; if p is a *float, it may generate a more complicated code sequence to load a floating-point value in c, truncate it, convert to int, and store the converted value into n. Without knowing the type of p, the compiler can't know which operation would be appropriate.
Likewise, the statement p++
may increase the address in p
by one, two, four, or some other number. The amount by which the address is increased will upon the declared type of p. If the compiler doesn't know the type of p, it won't know how to adjust the address.
It is possible to declare a pointer without specifying the type of the thing to which it points. The type of such a pointer is void*
. One must convert a void*
to a real pointer type before doing anything useful with it, however; the primary usefulness of void*
lies in the fact that if a pointer is converted to void*
, it may be passed around as a void*
by code which knows nothing about the pointer's actual type. If the pointer is eventually given to code which does know its type, and that code casts the pointer back to that type, the result will be the same as the pointer that had been converted to void*
.
Code which will have to handle pointers to things it knows nothing about can often usefully employ void*
for such purposes, but code which does know about the things to which pointers point should generally declare pointers of the proper type.