考虑以下计划:
int main()
{
int array[9];
const int (*p2)[9] = &array;
}
它在C ++中编译得很好(参见实时演示here)但在C中编译失败。默认情况下,GCC会发出以下警告。 (参见现场演示here)。
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中编译好。那么,上面的程序中发生了什么?
答案 0 :(得分:23)
在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]的指针,而不是类型指向数组的指针[9] ] int
和指向const int
的数组[9]的指针。