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. De todos modos, 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 consistencia 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

C++ no es tan estricto con los literales en lo referente a constantes. Puede escribir:

char * cp = "howdy";

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

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

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

char cp[] = "howdy";

Como los compiladores a menudo no imponen la diferencia no tiene porqué recordar que debe usar esta la última forma y la cuestión pasa a ser algo bastante sutil.