我曾經被這個警告困擾了好久好久,問了好些人,都説沒遇到過=_=…
問題代碼片段(與問題無關的代碼塊已被忽略):
size_t MyConv(const char *orginStr, const char *targetStr, ...) {
char **tmpIn = NULL;
char **tmpOut = NULL;
...
...
tmpIn = &orginStr;
tmpOut = &targetStr;
...
...
}
GCC編譯後會彈出如下警報:
sfind.c:887:8: warning: assigning to 'char **' from 'const char **' discards qualifiers in nested pointer types
[-Wincompatible-pointer-types-discards-qualifiers]
tmpIn = &orginStr;
^ ~~~~~~~~~
這條警告信息翻譯出來是“用類型表達式初始化“char \**” “const char \**”丟棄嵌套指針類型中的限定符。
”,個人表示很晦澀難懂。。。
後來翻閲《C專家編程》的時候,偶然間發現一個章節是討論const限定符的,認真看了下,頓時感慨自己學識太過淺薄。
上面的代碼中,實參const char \*orginStr
的const是修飾char orginStr
的,而char **tmpOut
是指向char *
類型變量的一個指針(此“char *”類型無修飾符),這兩點倒是沒有疑惑。但當二者互相賦值的時候,const char *orginStr
和char \**tmpOut
這兩個指針所指向的類型的修飾符不同。一個是const char orginStr
,帶了const修飾符,而另一個則是char *tmpOut
,並沒有const修飾符。指針變量賦值時,賦值語句左邊的指針所指向的類型必須具有賦值語句右邊的類型所擁有的全部修飾符,才能正常通過編譯,否則就會捨棄右邊變量多餘的修飾符。
以下內容摘自ANSI C標準手冊
兩個操作數都是指向有限定符或無限定符的相容類型的指針,左邊指針所指向的類型必須具有右邊指針所指向類型的全部限定符。
也就是説:
int *a = NULL;
const int *b = a;
上面這段代碼是可以正常通過編譯的,因為賦值語句左邊的指針指向的數據類型擁有了右邊的數據類型的所有修飾符(甚至還比右邊的多了一個const)而下面這段卻不行。
const int *a = NULL;
int b = a;