¿Por qué es esto incorrecto? El problema es que al asignar b = p recibo la siguiente advertencia: la assignment discards 'const' qualifiers from pointer target type .
int a = 4; int *b; const int *p = &a; b = p;Tiene un puntero que está definido para apuntar a un int que permite cambiar, b ; pero no lo inicias al principio.
Luego introduce un puntero a un int que no permite que se cambie.
Y lo apuntas a un int existente. Es decir, "Mira ese int, pero no lo cambies".
Luego, intenta asignar el valor del puntero "no toques esto" al puntero "oye, ten un int, haz lo que quieras".
El compilador le dice que es inconsistente allí, que se está contradiciendo a sí mismo y que realmente no puede querer decir lo que escribe en su código.
Por eso es incorrecto. Porque violas las reglas que tú mismo escribiste.
p es un puntero a un int constante y lo está asignando a un puntero a un int no constante.
p se define como un puntero const a int , lo que significa que no se puede usar para modificar el int al que apunta. Puede inicializarlo desde la dirección de un int que puede modificarse o no. Por el contrario, b es un puntero a int que se puede usar para modificar el int al que apunta. Solo debe inicializarse desde un puntero a int con la misma habilidad o la dirección de un int que sea modificable. b = p viola esta restricción, de ahí la advertencia.
Tenga en cuenta que b = &a está bien ya que a es modificable y p = b también está bien, solo restringiendo que p se use para modificar a .
Podría intentar silenciar la advertencia emitiendo p como (int *)p , pero no se recomienda: en este caso particular, p apunta a un int que se puede modificar, pero omitir la validación constante por parte del compilador hace que el código sea menos legible y más propenso a errores.
Calificar p como const int *p es una promesa que dice que no usaré p para modificar lo que apunta . La necesidad de romper esta promesa es una indicación de que algo no está bien estructurado en el programa.
No existe una forma recomendada de silenciar esta advertencia, pero simplemente puede cambiar el código para inicializar b desde &a esta manera:
int a = 4; int *b = &a; const int *p = b; Con el pedido publicado, podría escribir casualmente b = (int *)p; para tratar de silenciar la advertencia, pero un buen compilador como clang con advertencias habilitadas aún le advertirá con razón que este elenco es sospechoso ...
Si realmente necesita eliminar la constancia y desea silenciar la advertencia que aún ocurre con el obvio b = (int *)p; , podrías escribir esto:
b = (int *)(uintptr_t)(const void *)p; // avoid this!