2016-12-16 40 views
4

當我使用GCC 4.9.2編譯下面的程序時,我得到以下警告:從不兼容的指針類型傳遞'P'的參數1。但是,我沒有看到該計劃有任何問題。任何線索?GCC發出不兼容指針類型的警告

typedef int Row[10]; 

void P(const Row A[]) 
{ 
} 


int main(void) 
{ 
    Row A[10]; 

    P(A); 
    return 0; 
} 

下面是完整的輸出從GCC標準錯誤:

test.c: In function ‘main’: 
test.c:12:4: warning: passing argument 1 of ‘P’ from incompatible pointer type 
    P(A); 
    ^
test.c:3:6: note: expected ‘const int (*)[10]’ but argument is of type ‘int (*)[10]’ 
void P(const Row A[]) 
    ^

編輯:程序鏘3.5.0選項-pedantic -std=c89 -Wall完全編譯。

+2

你怎麼看待'const'預選賽什麼? –

+0

@SouravGhosh我認爲它承諾調用者參數* A *不會改變。 –

+0

是的,所以,功能期望.......? –

回答

4

擺脫的typedef,它應該成爲一點點清晰的:

void P (const int A [][10]) 
{ 
} 

int main(void) 
{ 
    int A[10][10]; 

    P(A); 
    return 0; 
} 

的問題是,在函數參數數組「衰變」到const int(*) [10]類型的指針,這是指向項目爲const的數組的指針。

該指針類型與您從main傳遞的內容不兼容,因爲該數組衰減到類型爲int(*)[10]的數組指針。

有一個「指針類型可以轉換爲限定指針類型」的規則。例如,int*的含義可以轉換爲const int*,但不是相反。但是這個規則在這裏不適用。

因爲「pointer-to-array」的限定版本是「const-pointer-to-array」,而不是「pointer-to-const-array」,這就是你在這裏的內容。

不幸的是,這是C語言的一個弱點:在使用數組指針時,你不能擁有const正確性。唯一的解決方案是一個非常醜陋的:

P((const int(*)[10]) A); 

這樣的情況下完全跳過const的正確性可能會更好,有利於可讀性。


編輯:C11,你可以做到這樣的,這是比較安全的類型,但它仍然依賴於執行投來電:

#define const_array_cast(arr, n) _Generic(arr, int(*)[n] : (const int(*)[n])arr) 

void P (const int A [][10]) 
{ 
} 


int main(void) 
{ 
    int A[10][10]; 

    P(const_array_cast(A,10)); 
    return 0; 
} 
+0

不需要將'const'傳遞給具有'const'參數的函數。函數中的'const'只是表示參數不會在函數中被修改。參見例如'strcmp'功能。 –

+0

該程序與Clang 3.5.0用選項'-pedantic -std = c89 -Wall'乾淨地編譯。這是否意味着Clang中存在一個錯誤? –

+2

@RishikeshRaje請再次閱讀我的答案,我明確表達了你的意思,這裏不適用。 – Lundin

-1

根據錯誤消息函數期望一個指向常量的指針。

typedef int Row[10]; 

void P(const Row A[]) 
{ 
} 


int main(void) 
{ 
    const Row A[10]; 

    P(A); 
    return 0; 
} 
+0

我認爲「當參數定義(const Row A [])的一部分僅在函數P的作用域內適用時,則爲「const」。 – cdcdcd

+1

這不回答問題。如果數組不是「const」,但OP僅僅需要const正確性,這很可能是這種情況。 – Lundin

相關問題