El estándar C ++ 11 (ISO / IEC 14882: 2011) dice en § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
Para C ++ está bien, ya que un puntero a un String Literal es dañino ya que cualquier intento de modificarlo provoca un bloqueo. Pero, ¿por qué es válido en C?
El C ++ 11 también dice:
char* p = (char*)"abc"; // OK: cast added
Lo que significa que si se agrega un reparto a la primera declaración, se vuelve válido.
¿Por qué la conversión hace que la segunda declaración sea válida en C ++ y en qué se diferencia de la primera? ¿Todavía no es dañino? Si es así, ¿por qué la norma dice que está bien?
char[]
en primer lugar. El segundo es unconst_cast
disfraz.OK
.const
, por lo que necesariamente no lo eranconst
.Respuestas:
Hasta C ++ 03, su primer ejemplo fue válido, pero utilizó una conversión implícita en desuso: un literal de cadena debe tratarse como de tipo
char const *
, ya que no puede modificar su contenido (sin causar un comportamiento indefinido).A partir de C ++ 11, la conversión implícita que había quedado en desuso se eliminó oficialmente, por lo que el código que depende de ella (como su primer ejemplo) ya no debería compilarse.
Ha notado una forma de permitir que el código se compile: aunque la conversión implícita se ha eliminado, una conversión explícita aún funciona, por lo que puede agregar un reparto. Yo no , sin embargo, considerar esta "fijar" el código.
La verdadera fijación del código requiere cambiar el tipo de puntero al tipo correcto:
En cuanto a por qué se permitió en C ++ (y todavía lo está en C): simplemente porque hay un montón de código existente que depende de esa conversión implícita, y romper el código (al menos sin alguna advertencia oficial) aparentemente pareció a los comités estándar como una mala idea.
fuente
char const *p = "abc";
es "válida y segura en ambos C y C ++", no es "válida y segura en cualquiera de C o de C ++".Es válido en C por razones históricas. C tradicionalmente especificaba que el tipo de literal de cadena era
char *
más queconst char *
, aunque lo calificaba diciendo que en realidad no se le permite modificarlo.Cuando usa un elenco, básicamente le está diciendo al compilador que conoce mejor que las reglas de coincidencia de tipos predeterminadas, y hace que la asignación sea correcta.
fuente
char[N]
y fue cambiado aconst char[N]
. Tiene información de tamaño adjunta.char[N]
pero no es,char*
por ejemplo,"abc"
eschar[4]
También puedes usar strdup :
fuente