不允许在类型“const int ** const”和“int **”之间初始化,为什么?

使用V1.8 z / OS XL C编译器,使用INFO(ALL)警告升级,我在下面代码的第4行收到以下警告:

WARNING CCN3196 Initialization between types "const int** const" and "int**" is not allowed. 1 int foo = 0; 2 int *ptr = &foo; 3 const int * const fixed_readonly_ptr = ptr; 4 const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

我无法理解为什么我会收到这个警告。 如果我可以为指向const int(第3行)的const指针分配一个int指针,那么为什么我不能将int指针的地址分配给指向const int的指针的const指针? 我错过了什么?

请注意,上面的代码是一个精简的示例,只是显示了我在少量代码中遇到的问题。 真正的上下文是我有一个const指针指向struct(struct s ** const),并将它作为参数传递给函数,该函数的参数被定义为指向const结构的const指针(const struct s **)常量)。 这是因为函数不会修改结构中的数据(因此是第一个const),并且它不会修改始终保存传入的地址的指针参数(因此第二个const)。 指向的指针的值可以通过这种方式改变(这就是**之间没有第三个const的原因)。

C规则是你可以将一个指向某个东西的指针转换成一个指向const的东西,但是这个东西必须是完全相同的类型,包括链中的const和volatile资格。

这条规则的基本原理是,如果允许这两行中的第二行:

 int *ptr; const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

那么这可以用来打破没有演员阵容的类型安全。

 const int i = 4; // OK, both sides have type const int * *fixed_ptr_to_readonly_ptr = &i; // the value of fixed_ptr_to_readonly_ptr is still &ptr // the value of ptr is now &i; *ptr = 5; // oops, attempt to change the value of i which is const 

这是一种类型安全违规。 考虑一下这段代码(我稍微改组了一下,以明确它是否适用于指针或指针,但语义上它意味着完全相同的事情):

 int* p = 0; int const** pp = &p; // presumably ok int const c = 123; *pp = &c; // okay, &c is int const*, and *p is int const* lvalue *p = 666; // okay, *p is int lvalue // wait, so we just changed the value of (const) c above, with no const_cast! 

这是类型安全违规。 您可能希望使用const int * const *。 请参阅http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17