Um ponteiro para void
é um tipo de ponteiro "genérico". A void *
pode ser convertido para qualquer outro tipo de ponteiro sem uma conversão explícita. Você não pode desreferenciar um void *
ponteiro ou fazer aritmética com ele; você deve convertê-lo em um ponteiro para um tipo de dados completo primeiro.
void *
é frequentemente usado em locais onde você precisa trabalhar com diferentes tipos de ponteiros no mesmo código. Um exemplo comumente citado é a função de biblioteca qsort
:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
base
é o endereço de uma matriz, nmemb
é o número de elementos na matriz, size
é o tamanho de cada elemento e compar
é um ponteiro para uma função que compara dois elementos da matriz. É assim chamado:
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);
As expressões de matriz iArr
, dArr
e lArr
são convertidos implicitamente a partir de tipos de matriz para tipos de ponteiro na chamada de função, e cada um é implicitamente convertido de "ponteiro a int
/ double
/ long
" a "ponteiro de void
".
As funções de comparação seriam parecidas com:
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;
}
Ao aceitar void *
, qsort
pode trabalhar com matrizes de qualquer tipo.
A desvantagem do uso void *
é que você joga a segurança de tipos pela janela e entra no tráfego que se aproxima. Não há nada para protegê-lo de usar a rotina de comparação errada:
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
compareInt
espera que seus argumentos apontem para int
s, mas na verdade está trabalhando com double
s. Não há como detectar esse problema no momento da compilação; você acabará com uma matriz distorcida.