void **和void *的编译警告

时间:2011-09-22 01:17:58

标签: c pointers

我有一个关于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;
}

3 个答案:

答案 0 :(得分:10)

void *a表示a指向未知类型的对象。但是,a本身不是未知类型,因为已知a具有类型void*。只有a指向的对象具有未知类型。

void **a表示a指向void*类型的对象。 *a指向的对象具有未知类型,但对象*a本身是类型为void*的指针。

&y是指向float*类型对象的指针。 &y不是指向void*类型对象的指针。

答案 1 :(得分:6)

C ++标准允许将任何指针隐式转换为 a void*。但是void**void*不是一回事;它是指向void*的指针。因此,它属于常规指针转换的规则(即:禁止使用强制转换,但有一些例外)。

答案 2 :(得分:3)

在其他答案中添加信息时,void*在C中充当通用指针类型。有一些关于它的通用:任何指针(指向函数的指针类型)都可以转换为void *并再次返回而不丢失信息,并且指针表达式(再次,除了指向函数的指针)可以隐式转换为void*。 (C ++的规则略有不同。)

您可能认为void**是指向指针的通用类型,但事实并非如此。它是指向特定类型的指针,即void*。实际上,C没有通用的指针指针类型。但它确实有一个通用的指针类型,因此任何试图使用void**作为通用指针指针类型的代码都可能只使用void*代替。