2011-09-22 167 views
4

我有一個關於void*void**的問題,我知道這是一個古老的問題,並已(在stackoverflow之前)詢問過(有點)。所以現在的問題是:編譯警告無效**和無效*

當我編譯這個代碼用gcc 4.4.3 ubuntu下10.10,我得到以下警告:

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; 
} 
+0

爲什麼選擇C++標籤?這個問題純粹是c。 –

回答

10

void *a意味着a指向未知類型的對象。但是,a本身並不是未知類型,因爲已知a的類型爲void*。只有a指向的對象具有未知類型。

void **a意味着a指向void*類型的對象。 *a指向的對象具有未知類型,但對象*a本身是類型爲void*的指針。

&y是指向float*類型的對象的指針。 &y不是指向void*類型的對象的指針。

+0

......等等......這實際上是有道理的! +1爲真棒解釋。 – quasiverse

+0

+1用於解釋說明。 –

+0

你會如何解決警告? – user10607

5

C++標準允許將任何指針隱式轉換爲 a void*。但是void**void*不是一回事;它是指向void*的指針。因此,它屬於規則指針轉換的規則(即:除非有一些例外,否則禁止沒有轉換)。

3

添加到其他答案中的信息中,void*充當C中的通用指針類型。有些東西是通用的:任何指針(除指針函數類型外)都可以轉換爲void *並且在不丟失信息的情況下再次返回,並且可以將指針表達式(再次,除了指向函數的指針)隱式轉換爲void*。 (C++有一些不同的規則。)

你可能會認爲void**是一個通用的指針指針類型,但它不是。它是指向特定類型的指針,即void*。實際上,C沒有通用的指針指針類型。但它確實有一個通用指針類型,因此任何試圖使用void**作爲通用指針指針類型的代碼可能只是使用void*代替。

相關問題