代码之家  ›  专栏  ›  技术社区  ›  Robert Groves

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

  •  2
  • Robert Groves  · 技术社区  · 15 年前

    使用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指针到const int(第3行),那么为什么我不能将int指针的地址分配给const指针到const int?我错过了什么?

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

    3 回复  |  直到 15 年前
        1
  •  5
  •   Pavel Minaev    15 年前

    这是一种违反安全规定的行为。考虑这个代码(我洗牌了) 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
  •  3
  •   CB Bailey    15 年前

    C规则是,您可以将指向某物的指针转换为指向常数某物的指针,但该某物必须是完全相同的类型,包括链下游的常数和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
  •  0
  •   Geerad    15 年前

    这是一种类型安全违规行为。您可能需要使用const int*const*。 看见 http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17