que - Advertencias de corrección de constor de doble puntero en C
punteros c++ (2)
La entrada de preguntas frecuentes vinculada por la otra respuesta explica por qué no se permite el siguiente código:
int **x = whatever;
const int **z = x;
Sin embargo, su código const int *const *z = x;
es bastante diferente, y no sufre el mismo defecto planteado por las preguntas frecuentes.
De hecho, conceptualmente no hay nada de malo en este último código. Es solo un defecto en la especificación C que no está permitido, y obliga a los programadores de C a incluir moldes feos en su código.
Hubiera sido posible para C usar las mismas reglas que C ++; sin embargo, el comité estándar de C no decidió hacer eso.
Un puntero a datos no const se puede convertir implícitamente en un puntero para const datos del mismo tipo:
int *x = NULL;
int const *y = x;
Agregar calificadores const adicionales para que coincida con la indirección adicional lógicamente debería funcionar de la misma manera:
int * *x = NULL;
int *const *y = x; /* okay */
int const *const *z = y; /* warning */
Sin embargo, la -Wall
esto con GCC o Clang con el -Wall
produce la siguiente advertencia:
test.c:4:23: warning: initializing ''int const *const *'' with an expression of type
''int *const *'' discards qualifiers in nested pointer types
int const *const *z = y; /* warning */
^ ~
¿Por qué agregar un calificador const
adicional "descartar calificadores en tipos de apuntadores anidados"?
La razón por la cual const
solo se puede agregar un nivel profundo es sutil, y se explica por la pregunta 11.10 en las preguntas frecuentes comp.lang.c.
Brevemente, considere este ejemplo estrechamente relacionado con el suyo:
const int i;
int *p;
int const **z = &p;
*z = &i;
/* Now p points to i */
C evita este problema al permitir que la asignación descarte los calificadores en el primer nivel apuntado (por lo que la asignación a z
aquí no está permitida).
Su ejemplo exacto no sufre este problema, porque const
el segundo nivel significa que la asignación a *z
no estaría permitida de todos modos. C ++ lo permitiría en este caso exacto, pero las reglas más simples de C no distinguen entre su caso y el ejemplo anterior.