I know that we have different pointers like int
, float
, and char
. A void
pointer is the only pointer which can hold all o
The type of a pointer in C tells the compiler what is the size of the memory block to be read in case you attempt to dereference it. In other words, when dereferencing an int pointer the compiler knows that 4 bytes have to be read after the address. That is why dereferencing a void pointer without casting it to a typed pointer is forbidden - in this case the compiler doesn't know how many bytes to read after the address.
When you iterate through the memory block pointed to by a pointer, it's necessary to know the size of the data type the memory contains. Say you have two pointers, a charcharptr and an intintptr, both pointing at memory at byte X. charptr+1 will point to the byte X+1, while intptr+1 will point to byte X+4.
A quick and dirty piece of badly written code to illustrate that:
#include <stdio.h>
int main()
{
char * cptr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
short * sptr = (short*)cptr;
int * iptr = (int*)cptr;
long long * lptr = (long long*)cptr;
printf ("CHAR: %d, +1: %d\n",cptr,cptr+1);
printf ("SHORT: %d, +1: %d\n",sptr,sptr+1);
printf ("INT: %d, +1: %d\n",iptr,iptr+1);
printf ("LONG LONG: %d, +1: %d\n",lptr,lptr+1);
}
This should:
The compiler needs to know the types pointed at otherwise all sorts of code won't work. Consider the following:
*a = *b + *c; // Should this add char? int? float? s_ptr->x = 0; // How does the compiler know anything about the structure s_ptr points to? a[5] = 0; // How far is a[5] from a[0]?
Not having types for pointers would be like not having types for anything. The compiler would be completely lost. In short, C and C++ are both strongly typed and this carries over to pointers for fairly obvious reasons.
Actually, it is the "pointer to void" which is to be explained.
In programming languages in general and in C in particular, we like types. Types are the basic safety net which checks whether we are doing something stupid, where "stupid" means "interpreting a bunch of bits for something they are not". It is possible to program without types, some languages are fully devoid of any kind of type (e.g. assembly or Forth), but this is not for the faint of heart and, generally speaking, programmer productivity seems to be greatly enhanced by use of types.
Therefore, when we have a pointer we want the computer to know what it may found at the end of the pointer. We want a "pointer to int" so that the computer checks that when we look at the bits which are at the end of the pointer, we look at them as an "int" and not as something else.
The "pointer to void" is the type-less pointer, which we use when the type system of C fails to capture what we are doing. It is a symptom of C not being able to follow the complexity of the code we are producing (or maybe the programmer was not good enough to express what he does within the constraints of the C type system). Hence, while "void *" is convenient in some situations, one should see it as the exception, and strive to avoid it.