abs*_*suu 1 c pointers constants
我的程序(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
}
Run Code Online (Sandbox Code Playgroud)
GCC 或 Clang 都可以编译,但两者都会在B 行中引发相同的“不兼容指针类型”警告。我对这个警告没有问题,因为const int **和int **肯定是两个兼容的指针类型。然而(在我看来),const int *和int *也是两个兼容的指针类型(A 行)。
因此我的问题是:为什么const int *和int *被视为兼容的指针类型?
GCC 警告消息的措辞不正确;违反的规则intp1 = temppp并不是 的操作数=必须兼容,而是它们必须符合某些约束。兼容性是这些限制中的因素之一,但它不是这里讨论的因素,因此该消息具有误导性。尽管问题指出 Clang 引发了 \xe2\x80\x9cincompleted-pointer-types\xe2\x80\x9d 警告,但我没有看到这一点;Compiler Explorer 上可用的每个版本的 Clang都会报告正确的错误消息,\xe2\x80\x9c 从 \'int **\' 分配给 \'const int **\' 会丢弃嵌套指针类型中的限定符。\xe2\x80\x9d
Anint *可以分配给 a const int *,因为简单分配的规则允许向直接指向的类型添加限定符。C 2018 6.5.16.1 说:
\n\n应满足下列条件之一:
\n\xe2\x80\xa6
\n\xe2\x80\x94 左操作数具有原子、限定或非限定指针类型,并且(考虑左值转换后左操作数将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且指向的类型左边的 to 拥有右边指向的类型的所有限定符;\xe2\x80\xa6
\n
const int *指向的非限定类型是int,指向的非限定类型int *也是int,并且int与其自身兼容。const int *此外,指向 的类型具有指向 的const int类型的所有限定符。int *int
相反,const int **指向的非限定类型是,指向的const int *非限定类型是,并且与 不兼容。(请注意, while指向限定类型,但它本身是非限定的;类型的对象可以更改为指向不同的;它不是限定的。) So不满足此约束,因此编译器会对此发出警告。int **int *const int *int *const int *const int *const intconstintp1 = temppp
不允许这样做的原因是它可能导致指向限定类型的指针指向没有该限定符的对象。C 2018 6.5.16.1 6 给出了一个示例,此处稍加修改并附有我的评论:
\nconst int **ipp;\nint *p;\nconst int i = 1;\n\n/* The next line violates the constraints because `&p` is an `int **`, and\n it is assigned to a `const int **`.\n For illustration, suppose we suspend the constraint and allow it.\n*/\nipp = &p;\n\n/* In the following, both `*ipp` and `&i` are `const int *`, so this is\n an ordinary assignment of identical types.\n*/\n*ipp = &i;\n\n/* In the following, `*p` is an `int`, to which an `int` is assigned. So\n this is an ordinary assignment of identical types. However, `p` points\n to `i`, which is `const`, so this assignment would change the value of\n a `const` object. The assignment `ipp = &p` above enabled this, so it\n is unsafe and should be disallowed.\n*/\n*p = 0;\nRun Code Online (Sandbox Code Playgroud)\n\n\n因此我的问题是:为什么
\nconst int *和int *被视为兼容的指针类型?
它们不是兼容的指针类型。如上所述,不允许赋值的原因是有关限定符的规则,而不是有关兼容类型的规则。
\nC 中兼容类型的概念不是关于一种类型是否可以分配给另一种类型,而是关于两种类型除了我们不知道的部分之外是否实际上相同。例如,三个数组int和一个未指定数量的数组int是兼容的\xe2\x80\x94我们所知道的关于这两种类型的所有部分都是相同的。如果未指定的部分完成,它们可能是相同的。类似地,接受未知参数的函数返回与接受某些声明参数的void *函数返回兼容。void *这个兼容性问题与作业中的限定符问题无关。
| 归档时间: |
|
| 查看次数: |
1997 次 |
| 最近记录: |