8.2.3. Asignación y comprobación de tipos

C++ es muy exigente en lo referente a la comprobación de tipos y esto se extiende a la asignación de punteros. Puede asignar la dirección de una variable no constante a un puntero constante porque simplemente está prometiendo no cambiar algo que puede cambiarse. Sin embargo, no puede asignar la dirección de una variable constante a un puntero no constante porque entonces está diciendo que podría modificar la variable a través del puntero. Por supuesto, siempre puede usar «un molde» para forzar la asignación, pero eso es siempre una mala práctica de programación ya que rompe la constancia de la variable además del grado de seguridad que ofrece el especificador const. Por ejemplo:

//: C08:PointerAssignment.cpp
int d = 1;
const int e = 2;
int* u = &d; // OK -- d not const
//! int* v = &e; // Illegal -- e const
int* w = (int*)&e; // Legal but bad practice
int main() {} ///:~

Listado 8.4. C08/PointerAssignment.cpp


Aunque C++ ayuda a evitar errores, no le protege de usted mismo si se empeña en romper los mecanismos de seguridad.

Literales de cadena

El lugar en el que no se impone una constancia estricta es en los literales de cadena. Puede escribir:

char * cp = "howdy";

y el compilador lo aceptará sin objeción. Técnicamente esto supone un error porque el compilador crea el literal de cadena («howdy» en este caso) como un array de caracteres constante, y el resultado del array de caracteres entrecomillado es la dirección de memoria del primer elemento. Modificar cualquiera de los caracteres del array es un error en tiempo de ejecución, aunque no todos los compiladores lo imponen correctamente.

Así que los literales de cadena son en realidad arrays de caracteres constantes. Por supuesto, el compilador le permite tratarlos como no constantes porque existe mucho código C que depende de ello. Sin embargo, si intenta cambiar los valores de un literal, el resultado no está definido, aunque probablemente funcione en muchos computadores.

Si quiere poder modificar una cadena, debe ponerla en un array:

char cp[] = "howdy";

Como los compiladores a menudo no imponen la diferencia, nada le recordará que debe usar esta última forma, y la cuestión pasa a ser algo bastante sutil.