Advertencias de corrección de constor de doble puntero en C

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 nesteds”?

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.

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 progtwigdores 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.