考虑以下计划:
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中,带有限定符的数组的指针与指向其他限定类型的指针的工作方式类似.例如,type的值
int (*)[5]
可用于初始化类型的变量const int (*)[5]
.这些类型在ISO C中是不兼容的,因为const
限定符正式附加到数组的元素类型而不是数组本身.
C标准说(部分:§6.7.3/ 9):
如果数组类型的规范包含任何类型限定符,则元素类型是合格的,而不是数组类型.[...]
现在看看C++标准(第3.9.3/5节):
[...]应用于数组类型的Cv限定符附加到底层元素类型,因此符号"
cv T
,"whereT
是数组类型,指的是元素是如此限定的数组.元素为cv-qualified的数组类型也被认为具有与其元素相同的cv-qualifications.[ 例如:typedef char CA[5]; typedef const char CC; CC arr1[5] = { 0 }; const CA arr2 = { 0 };类型两者的
arr1
和arr2
是"5常量字符阵列"和阵列型被认为是合格const-.-endexample]
因此,初始化
const int (*p2)[9] = &array;
是类型的分配指针阵列[9]的int
至指针常量的阵列[9] int
.这不是类似于分配int *
到一个const int *
其中const
被直接施加到所述输入指针指向对象.const int(*)[9]
在C中,const
应用于数组对象的元素而不是指针指向的对象的情况并非如此.这使得上述初始化不兼容.
此规则在C++中已更改.正如const
应用于数组对象本身一样,赋值是在相同类型的指针int
之间指向const数组[9]而不是指向数组[9]的int
类型指针和指向const数组[9]的指针int
.