Un pointeur vers void
est un type de pointeur "générique". A void *
peut être converti en tout autre type de pointeur sans conversion explicite. Vous ne pouvez pas déréférencer un void *
ou faire de l'arithmétique de pointeur avec lui; vous devez d'abord le convertir en pointeur vers un type de données complet.
void *
est souvent utilisé dans les endroits où vous devez pouvoir travailler avec différents types de pointeurs dans le même code. Un exemple couramment cité est la fonction de bibliothèque qsort
:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
base
est l'adresse d'un tableau, nmemb
est le nombre d'éléments dans le tableau, size
est la taille de chaque élément et compar
est un pointeur vers une fonction qui compare deux éléments du tableau. Il s'appelle ainsi:
int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);
Les expressions du tableau iArr
, dArr
et lArr
sont convertis implicitement des types de tableau à des types de pointeur dans l'appel de fonction, et chacun est implicitement converti de « pointeur vers int
/ double
/ long
» à « pointeur void
».
Les fonctions de comparaison ressembleraient à quelque chose comme:
int compareInt(const void *lhs, const void *rhs)
{
const int *x = lhs; // convert void * to int * by assignment
const int *y = rhs;
if (*x > *y) return 1;
if (*x == *y) return 0;
return -1;
}
En acceptant void *
, qsort
peut travailler avec des tableaux de tout type.
L'inconvénient de l'utilisation void *
est que vous jetez la sécurité de type par la fenêtre et dans le trafic venant en sens inverse. Rien ne vous empêche d'utiliser la mauvaise routine de comparaison:
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
compareInt
s'attend à ce que ses arguments pointent vers int
s, mais travaille en fait avec l' double
art. Il n'y a aucun moyen d'attraper ce problème au moment de la compilation; vous vous retrouverez juste avec un tableau mal trié.