No se permite la inicialización entre los tipos “const int ** const” y “int **”, ¿por qué?

StackOverflow https://stackoverflow.com/questions/1468148

Pregunta

El uso de z / OS V1.8 XL compilador de C, con advertencias utilice el gato utilizando INFO (ALL), me sale el siguiente mensaje de advertencia en la línea 4 del código de abajo:

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;

No puedo hacerme a qué estoy recibiendo esta advertencia. Si puedo asignar un puntero int a un puntero constante a const int (línea 3), entonces por qué no puedo asignar la dirección de un puntero int a un puntero constante a puntero a const int? ¿Qué me falta?

Tenga en cuenta que el código anterior es un ejemplo adelgazado simplemente mostrando el problema que estoy encontrando en una pequeña cantidad de código. El contexto real es que tengo un puntero constante a puntero a struct (struct s ** const) y estoy pasando como argumento a una función que está parámetro se define como un puntero constante a puntero a const struct (const struct s ** const). Esto se debe a la función no modificará los datos en la estructura (por lo tanto la primera const) y no modificar el parámetro de puntero que siempre contiene la dirección aprobada en (de ahí el segundo const). El valor del puntero señaló que puede ser cambiado por el camino (que es por qué no hay una tercera const entre el **).

¿Fue útil?

Solución

La regla C es que se puede convertir un puntero a algo que un puntero a const algo, pero ese algo tiene que ser exactamente el mismo tipo incluyendo const y calificaciones volátiles más abajo en la cadena.

La razón de esta regla es que si se permitiera la segunda de estas dos líneas:

int *ptr;

const int ** const fixed_ptr_to_readonly_ptr = &ptr;

entonces este puede ser utilizado para romper la seguridad de tipos sin una conversión.

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

Otros consejos

Es una violación de seguridad de tipo. Considere este código (Barajé const un poco para que quede claro si se aplica a puntero o pointee, pero semánticamente que significa exactamente lo mismo):

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!

Esto es una violación seguridad de tipos. Es posible que desee utilizar un const * const int * en su lugar. Ver http://www.parashift.com/c++ -FAQ-lite / const-correctness.html # faq-18.17

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top