tags:

views:

611

answers:

10

I know that we have different pointers like int, float, and char. A void pointer is the only pointer which can hold all others.

Do the other pointers exist only for the flexibility to do pointer arithmetic?

Is there any other reason that pointers other than void are present in C language?

+17  A: 

Type safety. Defining the type of pointers helps the compiler find errors where you are trying to use data of the wrong type through a pointer. That's the reason C has types in the first place.

Max Shawabkeh
-1, very misleading: existence of types doesn't imply existence of type safety. It is principally the fact that type casting of pointer ref/dereferencing is so completely unconstrained that C is a type unsafe language. Instead, the point is that types describe the semantics of pointer ref/dereferencing.
Charles Stewart
+2  A: 

When You use pointer to float or int (for example) compiler knows how many bytes it should take from memory (sizeof(int) for int* for example).

With void You would have to tell each time to compiler how many bytes it have to take (by writing (int*)some_void_ptr for example.

But this is great simplification.

matekm
A: 

Two Words: Type Safety

There's a little tidbit on type safety (or lack thereof) in C on Wikipedia that might shed some light for you.

Michael Krauklis
-1: cf. my comment on Max's answer.
Charles Stewart
+6  A: 
int o = 12;
void *i = &o;

How would you access the int that i points to if there were only void pointers and no int*. You might know that on your platform an int is 4 bytes so you could memcpy 4 bytes from the start of whatever the void* points to into a temporary int and then use that. But that's not very convenient.

Or given a

struct Pair {
   char *first;
   char *second;
};

how useful would a void pointer to struct Pair be ? You'd likely want to access its first member and that's a lot of work if you couldn't have a pointer to a struct Pair.

Anonym
+1 for answering the question without making false assertions.
Charles Stewart
A: 

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 char*charptr and an int*intptr, 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:

  • generate warnings about casting pointers of different sizes (type safety),
  • output identical numbers in the first column (all pointers point to the same address in memory), but different numbers in the 2nd column (which is base address + size of the pointer's type: 1, 2, 4 and 8 bytes).
mingos
+9  A: 

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.

phkahler
Err, "strongly" typed means that the language can't do incoherent typecasting. WP: "Disallowing any kind of type conversion. Values of one type cannot be converted to another type, explicitly or implicitly." http://en.wikipedia.org/wiki/Strongly_typed_programming_language
Charles Stewart
I'm using a weaker definition as explained further down on the wikipedia page you link :-) My bad though.
phkahler
+1  A: 

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.

Thomas Pornin
Pointer to void exists because there's no base object type.
Steven Sudit
@Steven, no it doesn't C doesn't have objects, sometimes a blob simply has no type, not a base type, not an object/struct/whatever-you-want-to-call-it type, not any type. The use of pointer-to-unknown-type is just one of its uses.
wich
@wich: Languages such as C# have a base `object` type, which all instances can be up-cast to (whether Int32 or Employee). Therefore, a C# `object` reference serves the same function as a C++ `void` pointer: it can refer to anything.
Steven Sudit
@wich: Trivially, a BLOB is a byte array.
Steven Sudit
@Steven I'm not talking about a binary large object, I'm just talking about a bag of data, it can be anything, completely untyped, might come from a source that doesn't even have a byte size, but is a bit stream, or even from a system with a different memory element size than the native host etc. etc.
wich
@Steven C# and C++ are not in the picture here, this question is about C. And yes I know a void* can refer to anything, object can NOT refer to anything, only to everything derived from it, within the context of the language that is everything, but the context of a computer is larger than a programming language. Again pointer-to-unknown-type is just one of its uses.
wich
In C, if handed an area of memory, your least common denominator is to interpret it as an array of bytes. This is what I meant by saying that, trivially, a blob is a byte array, not fundamentally untyped.
Steven Sudit
Could you give an example of a void pointer that is meaningfully different from a pointer to an unknown type?
Steven Sudit
A: 

Is there any other reason that pointers other than void are present in C language?

They are an awesome way to handle memory chunks freely. : )

SDReyes
Union types are better.
Charles Stewart
Yep, I agree! : )
SDReyes
+1  A: 

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.

Blagovest Buyukliev
+4  A: 

Dead simple:

void* p;
*p; // compile error!

Or to put it in words; a void pointer can not be dereferenced.

Perhaps you should rename the question why do we have pointers, or rather don't and just search for that question on SO.

wich