const en el lenguaje C permite restringir la modificabilidad de un objeto. Al trabajar con parámetros de función, esto ayuda a proteger los datos de cambios accidentales. La diferencia clave en la declaración depende de a qué se refiere el modificador const y dónde se encuentra en relación con el puntero.
Ejemplo de distintas declaraciones:
void func(const int *ptr); // puntero a un int constante void func(int * const ptr); // puntero constante a un int void func(const int * const ptr); // puntero constante a un int constante
const int *ptr — los datos son inmutables, el puntero se puede reasignar.int *const ptr — los datos son mutables, pero el puntero no se puede reasignar.const int *const ptr — ni los datos ni el puntero se pueden modificar dentro de la función.Uso correcto de const: permite:
void print_array(const int *arr, size_t n) { for (size_t i = 0; i < n; ++i) { printf("%d\n", arr[i]); // arr[i] = 10; // error: intento de modificar datos const } }
Pregunta: ¿Se puede asignar la dirección de una variable constante a un puntero común?
Respuesta incorrecta esperada: "Sí, si se quita const en la declaración del puntero, el compilador permite."
Respuesta correcta: Está permitido "bajar const" solo con conversión de tipos (casting) explícita, pero esto conduce a comportamiento indefinido al intentar modificar un objeto declarado como const. No se debe hacer esto, ya que viola la semántica de const y puede dar lugar a errores en tiempo de ejecución.
Ejemplo:
const int x = 5; int *ptr = (int*)&x; *ptr = 10; // UB: modificación de un objeto const
Historia
En un gran proyecto, un programador intentó eludir la protección const, convirtiendo un puntero const a uno común y modificando datos en la sección de memoria de solo lectura. En algunas plataformas, esto provocó el cierre inesperado del programa (fallo de segmentación), y en otros, errores sutiles difíciles de depurar.
Historia
En una biblioteca para trabajar con arrays, el desarrollador olvidó declarar los parámetros como const. Como resultado, una llamada incorrecta a la función modificó accidentalmente los datos originales, lo que llevó a la desincronización del estado del array y graves errores en los siguientes bloques de procesamiento.
Historia
Al escribir una función callback que se pasaba a una biblioteca ajena, se olvidó especificar const para el búfer de entrada. La biblioteca intentó modificar los datos en una cadena constante, lo que causó un fallo en algunos sistemas operativos y prolongadas investigaciones sobre la fuente del problema.