Avertissement de compilation pour annulation ** et annulation *

J’ai une question à propos de void* et de void** et je sais que c‘est en quelque sorte une vieille question et qu’elle a déjà été posée (quelque peu) dans stackoverflow. La question est donc la suivante:

Lorsque je comstack ce code avec gcc 4.4.3 sous Ubuntu 10.10, je reçois l’avertissement suivant:

 zz.c: In function 'main': zz.c:21: warning: passing argument 1 of 'bar' from incompatible pointer type zz.c:9: note: expected 'void **' but argument is of type 'float **' 

pourquoi est-ce que son ok pour passer la variable x en tant qu’argument de foo () mais ce n’est pas ok pour passer la variable y en tant qu’argument de bar (). Je peux résoudre ce problème en convertissant explicitement les deux variables en void* et void** comme prévu.

 void foo (void* a){ } void bar(void **a){ *a = (float *) malloc(100*sizeof(float)); } int main (){ float *x = (float*) malloc(100*sizeof(float)); foo(x); free(x); float *y; bar(&y); free(y); return 0; } 

void *a signifie que a pointe sur un object de type inconnu. Cependant, a lui-même n’est pas un type inconnu car il est connu que le type est void* . Seul l’object sur lequel pointe un type inconnu.

void **a signifie que a pointe sur un object de type void* . L’object *a pointé sur a un type inconnu, mais l’object *a lui-même est un pointeur de type void* .

&y est un pointeur sur un object de type float* . &y n’est pas un pointeur sur un object de type void* .

La norme C ++ permet de convertir implicitement tout pointeur en void* . Mais un void** n’est pas la même chose qu’un void* ; c’est un pointeur sur un void* . Par conséquent, il est soumis aux règles applicables aux conversions de pointeurs standard (c’est-à-dire: interdit sans transtypage, à quelques exceptions près).

En ajoutant aux informations des autres réponses, void* agit comme un type de pointeur générique en C. Certains éléments sont génériques à son sujet: tout pointeur (autre qu’un type de pointeur sur une fonction) peut être converti en void * et inversement. encore une fois sans perte d’information, et une expression de pointeur (encore une fois, autre que pointeur vers fonction) peut être implicitement convertie en void* . (C ++ a des règles légèrement différentes.)

Vous pourriez penser que void** est un type générique de pointeur à pointeur, mais ce n’est pas le cas. C’est un pointeur sur un type spécifique, à savoir void* . En fait, C n’a pas de type générique de pointeur à pointeur. Mais il a un type de pointeur générique, donc tout code qui essaie d’utiliser void** comme type de pointeur à pointeur générique peut probablement simplement utiliser void* place.