Pointers void*
precedes C++ and templates as a mechanism to deal with "generic" types in C. To be more specific void
represents the absence of type, which can be understood as the presence of any kind.
As you have already discovered, it is possible to assign a int
, char
or any other type to a void*
.
With void*
functions that do not need to know the type details can do their job. Programmer, who knows the type, can do the Casts necessary. Note that absence of types basically puts the responsibility on typing on the back of the programmer .
#Why is that useful?
One of the best examples of using void*
is the function qsort
, whose signature is:
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void*,const void*));
With the qsort
we can order an array base
of any kind. You only need to define a function of the type int(const void*, const void*)
able to compare array types base
.
Example:
int compare(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
//...
int values[] = { 40, 10, 100, 90, 20, 25 };
qsort (values, 6, sizeof(int), compare);
You could have a method to compare char*
, or who knows for a specific type of struct
or anything else. Thanks to pointers void
the function qsort
is "generic".
But and functions that return void pointers*?
The idea is the same. Generic Apis can work with multiple return types. A good example are the pair of functions int pthread_setspecific(pthread_key_t key, const void *value)
and void *pthread_getspecific(pthread_key_t key)
of pthreads.h
. You can store and recover any kind of value thanks to the use of void*
.
Other good examples are the functions alloc as well mentioned in the previous answers. In c you do not need or should do cast of the result of malloc
(That changed in C++):
// C
int *arr= malloc(sizeof(int)*length);
// C++ escrito para ser compatível com C
int *arr= (int *)malloc(sizeof(int)*length);
// C++ "de verdade"
int *arr= new int[length];
// C++11 - Melhor ainda, esqueça o delete
std::unique_ptr<int[]> arr(new int[10]);
- [http://www.cplusplus.com/ - qsort][1]
- [Open Group - pthread_setspecific][2]
[1]: http://www.cplusplus.com/reference/cstdlib/qsort/
[2]: http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_getspecific.html
+1. Just one detail: it is not a good practice to cast the malloc return in C, although it is mandatory in C++. A good argument here (in English): http://stackoverflow.com/a/605858/1796236
– Pablo Almeida
@Pablo Yes, excellent observation.
– Victor Stafusa
Thanks for the explanation, I will have a lot of good information regarding the void.
– gato