Initialization between types “const int** const” and “int**” is not allowed, why?

两盒软妹~` 提交于 2019-12-14 02:18:18

问题


Using V1.8 z/OS XL C compiler, with warnings jacked-up using INFO(ALL), I get the following warning on line 4 of the code below:

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;

I can't wrap my head around why I'm getting this warning. If I can assign an int pointer to a const pointer to const int (line 3), then why can't I assign the address of an int pointer to a const pointer to pointer to const int? What am I missing?

Note the code above is a slimmed down example just showing the issue I'm encountering in a small amount of code. The real context is that I have a const pointer to pointer to struct (struct s** const) and am passing it as an argument to a function who's parameter is defined as a const pointer to pointer to const struct (const struct s** const). This is because the function will not modify the data in the struct (hence the first const) and it does not modify the pointer parameter which always holds the address passed in (hence the second const). The value of the pointer pointed to may be changed by the way (which is why there is NOT a third const in between the **).


回答1:


The C rule is that you can convert a pointer to something to a pointer to const something, but that something has to be exactly the same type including const and volatile qualifications further down the chain.

The rationale for this rule is that if the second of these two lines were allowed:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

then this can be used to break type safety without a cast.

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



回答2:


It's a type safety violation. Consider this code (I shuffled const around a bit to make it clear whether it applies to pointer or pointee, but semantically it means exact same thing):

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!



回答3:


This is a type-safety violation. You probably want to use a const int * const * instead. See http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17



来源:https://stackoverflow.com/questions/1468148/initialization-between-types-const-int-const-and-int-is-not-allowed-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!