void **和void *的编译警告
我有一个关于void*
和void**
,我知道这是一个老问题,并且在stackoverflow之前已经被问过(有点)。 所以问题如下:
当我在ubuntu 10.10下使用gcc 4.4.3编译此代码时,我收到以下警告:
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 **'
为什么将变量x作为foo()的参数传递是可以的,但是将变量y作为bar()的参数传递是不行的。 我可以通过将两个变量显式地转换为void*
和void**
来解决这个问题。
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
表示指向未知类型的对象。 但是, a
本身并不是未知类型,因为已知类型为void*
。 只有指向的对象具有未知类型。
void **a
表示指向void*
类型的对象。 *a
指向的对象具有未知类型,但对象*a
本身是类型为void*
的指针。
&y
是指向float*
类型的对象的指针。 &y
不是指向void*
类型的对象的指针。
C ++标准允许任何指针隐式转换为 void*
。 但是void**
与void*
; 它是指向void*
的指针。 因此,它属于常规指针转换的规则(即:禁止使用强制转换,但有一些例外)。
添加到其他答案中的信息, void*
在C中充当通用指针类型。有些东西是通用的:任何指针(指向函数的指针类型)都可以转换为void *并返回再次没有信息丢失,并且指针表达式(再次,除了指向函数的指针)可以隐式转换为void*
。 (C ++的规则略有不同。)
您可能认为void**
是指向指针的通用类型,但事实并非如此。 它是指向特定类型的指针,即void*
。 实际上,C没有通用的指针指针类型。 但它确实有一个通用的指针类型,因此任何试图使用void**
作为通用指针指针类型的代码都可能只使用void*
。