在C&C ++中使用const限定符指向数组的指针
考虑以下计划:
int main() { int array[9]; const int (*p2)[9] = &array; }
它在C ++中编译良好(参见此处的实时演示)但在C中编译失败。默认情况下,GCC会发出以下警告。 (见此处的现场演示)。
prog.c: In function 'main': prog.c:4:26: warning: initialization from incompatible pointer type [enabled by default] const int (*p2)[9] = &array;
但如果我使用-pedantic-errors
选项:
gcc -Os -s -Wall -std=c11 -pedantic-errors -o constptr constptr.c
它给了我以下编译器错误
constptr.c:4:26: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
为什么它在C中编译失败但在C ++中没有? C&C ++标准对此有何看法?
如果我在数组声明语句中使用const限定符,它也可以在C中编译好。 那么,上面的程序中发生了什么?
GCC-GNU
在GNU C中,带有限定符的数组的指针与指向其他限定类型的指针的工作方式类似。 例如,
int (*)[5]
类型的值可用于初始化const int (*)[5]
类型的变量。 这些类型在ISO C中是不兼容的,因为const
限定符正式附加到数组的元素类型而不是数组本身 。
C标准说(部分:§6.7.3/ 9):
如果数组类型的规范包含任何类型限定符,则元素类型是合格的, 而不是数组类型 。[…]
现在看看C ++标准(第3.9.3 / 5节):
[…]应用于数组类型的Cv限定符附加到底层元素类型,因此符号“
cv T
”(其中T
是数组类型)是指其元素是如此限定的数组。 元素为cv-qualified的数组类型也被认为具有与其元素相同的cv资格 。 [ 例如 :typedef char CA[5]; typedef const char CC; CC arr1[5] = { 0 }; const CA arr2 = { 0 };
arr1
和arr2
的类型都是“5个const char 的数组 ” , 并且数组类型被认为是const限定的 。 -endexample]
因此,初始化
const int (*p2)[9] = &array;
是指向int
数组[9]的类型指针到 指向const int
数组[9]的指针 。 这与将int *
赋值给const int *
类似,其中const
直接应用于指针指向的对象类型 。 const int(*)[9]
不是这种情况,其中,在C中, const
应用于数组对象的元素而不是指针指向的对象。 这使得上述初始化不兼容。
此规则在C ++中已更改。 当const
应用于数组对象本身时,赋值在相同类型的指针之间, 指向int
const数组[9],而不是指向 int
数组[9]的类型指针和指向const int
数组[9]的指针 。