【问题标题】:Pointer to array with const qualifier in C & C++在 C 和 C++ 中使用 const 限定符指向数组的指针
【发布时间】:2016-04-02 00:14:19
【问题描述】:

考虑以下程序:

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 中也可以正常编译。那么,在上面的程序中发生了什么?

【问题讨论】:

标签: c++ c arrays pointers constants


【解决方案1】:

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 限定的数组类型也被认为具有与其元素相同的 cv 限定。 [例子

 typedef char CA[5];
 typedef const char CC;
 CC arr1[5] = { 0 };
 const CA arr2 = { 0 };

arr1arr2 的类型都是“5 个 const char 的数组”数组类型被认为是 const 限定的。 ——结束示例]

因此,初始化

const int (*p2)[9] = &array;  

将类型指向int的数组[9]的指针分配给指向常量int的数组[9]的指针。这与将int * 分配给const int * 不同,其中const 直接应用于指针指向的对象类型const int(*)[9] 不是这种情况,在 C 中,const 应用于数组对象的元素,而不是指针指向的对象。这使得上述初始化不兼容。

此规则在 C++ 中已更改。由于 const 应用于数组对象本身,因此赋值是在相同类型 pointer to const array[9] of int 而不是类型 pointer to array[9] of @987654342 @指向 const int 的数组[9] 的指针。

【讨论】:

  • 我将其称为 ISO C 中的错误。这没有任何意义。您应该始终能够将const 添加到任何级别的指针目标。
  • @TomKarzes; 您应该始终能够将const 添加到任何级别的指针目标No. Not in C
  • @TomKarzes 不,你不应该,例如int **const int ** 之间众所周知的不兼容(在 C++ 中也是不兼容的)。如果存在这种隐式转换,则可以在不使用强制转换的情况下写入 const 对象。
  • @TomKarzes 的危害在于您可以编写修改 const 对象的代码(导致未定义的行为)而不会收到任何编译器警告或错误。 See here for full description
  • @TomKarzes:早在安全气囊出现之前,汽车就已经非常有用了。我们要删除它们吗?
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多