【问题标题】:Initialization between types "const int** const" and "int**" is not allowed, why?类型“const int** const”和“int**”之间的初始化是不允许的,为什么?
【发布时间】:2010-11-30 21:19:23
【问题描述】:

使用 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;

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

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

【问题讨论】:

  • Pavel 和 Charles 已经非常清楚为什么编译器会警告我。我对你们俩都投了赞成票,但感谢 Charles 从 C 的角度对其进行了分解(尽管两个答案非常相似,并说明了发出警告的原因)。

标签: c pointers casting zos xlc


【解决方案1】:

这是一种类型安全违规。考虑一下这段代码(我改组了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!

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      【解决方案3】:

      这是违反类型安全的。您可能想改用 const int * const * 。 见http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17

      【讨论】:

      • const int * const * 只对 C++ 有帮助,对 C 没有帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多