我的程式(https://godbolt.org/z/Y93eG7K7s):
int main(){
int temp = 0;
int* tempp = &temp;
int** temppp = &tempp;
int*** tempppp = &temppp;
const int* intp0;
intp0 = tempp; // A
const int** intp1;
intp1 = temppp; // B
}
GCC 或 Clang 都可以編譯,但兩者都會在B 行引發相同的“不兼容指標型別”警告。我對那個警告沒有任何問題,因為const int **并且int **絕對是兼容的指標型別中的兩個。但是(在我看來),const int *并且int *也是兩個兼容的指標型別(第 A 行)。
因此我的問題是:為什么const int *和int *被認為是兼容的指標型別?
uj5u.com熱心網友回復:
GCC 警告資訊措辭不正確;違反的規則intp1 = temppp不是 的運算元=必須兼容,而是它們必須符合某些約束。兼容性是這些限制中的一個因素,但它不是這里的問題因素,因此錯誤訊息具有誤導性。盡管問題指出 Clang 提出了“不兼容的指標型別”警告,但我沒有看到這一點;Compiler Explorer 上可用的每個 Clang 版本都會報告正確的錯誤訊息,“從 'int **' 分配給 'const int **' 會丟棄嵌套指標型別中的限定符。”
Anint *可以分配給 aconst int *因為簡單分配的規則允許將限定符添加到直接指向的型別。C 2018 6.5.16.1 說:
應滿足下列條件之一:
…
— 左運算元具有原子、限定或非限定指標型別,并且(考慮左運算元在左值轉換后將具有的型別)兩個運算元都是指向兼容型別的限定或非限定版本的指標,并且左指向的型別具有right 指向的型別的所有限定符;…
指向的非限定型別is ,const int *指向int的非限定型別int *也是int, 并且int與自身兼容。此外,指向 的型別具有const int *指向的const int型別的所有限定符。int *int
相反,const int **指向 is的不合格型別和指向isconst int *的不合格型別與不兼容。(請注意,雖然指向限定型別??,但它本身是不限定的;型別的物件可能會更改為指向不同的;它不是限定的。)因此不滿足此約束,因此編譯器會發出警告。int **int *const int *int *const int *const int *const intconstintp1 = temppp
不允許這樣做的原因是它可能導致指向限定型別??的指標指向沒有該限定符的物件。C 2018 6.5.16.1 6 給出了一個示例,此處顯示的內容稍作修改,并附有我的評論:
const int *ipp;
int *p;
const int i = 1;
/* The next line violates the constraints because `&p` is an `int **`, and
it is assigned to a `const int **`. Suppose it is allowed.
*/
ipp = &p;
/* In the following, both `*ipp` and `&i` are `const int *`, so this is
an ordinary assignment of identical types.
*/
*ipp = &i;
/* In the following, `*p` is an `int`, to which an `int` is assigned. So
this is an ordinary assignment of identical types. However, `p` points
to `i`, which is `const`, so this assignment would change the value of
a `const` object. The assignment `ipp = &p` above enabled this, so it
is unsafe and should be disallowed.
*/
*p = 0;
因此我的問題是:為什么
const int *和int *被認為是兼容的指標型別?
它們不是兼容的指標型別。如上所述,不允許賦值的原因是關于限定符的規則,而不是關于兼容型別的規則。
The notion of compatible types in C is not about whether one type may be assigned to another type but about whether two types are actually the same except for the parts we do not know about them. For example, an array of three int and an array of an unspecified number of int are compatible—all the parts we know about these two types are the same. They could be the same if the unspecified part is completed. Similarly, a function returning void * that takes unknown parameters is compatible with a function returning void * that takes certain declared parameters. This issue of compatibility is not related to the issue of qualifiers in assignments.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425201.html
上一篇:放置新操作員
下一篇:使用指標更新二叉樹
