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