Recientemente he estado aprendiendo C ++ y me he dado cuenta de que los literales de cadena en C ++ tienen que ser constantes, mientras que en C no. Aquí hay un ejemplo. El siguiente código sería válido en C, pero no en C ++:

char* str = "Hello World";

¿Alguien podría explicar por qué?

44
Serket 5 may. 2020 a las 00:23

2 respuestas

La mejor respuesta

Ampliando un poco la respuesta de Christian Gibbons ...

En C, los literales de cadena como "Hello World" se almacenan en matrices de char de modo que sean visibles durante la vida útil del programa. Se supone que se supone que los literales de cadena son inmutables, y algunas implementaciones los almacenarán en un segmento de memoria de solo lectura (de modo que intentar modificar el contenido del literal provocará un error de tiempo de ejecución). Algunas implementaciones no lo hacen, e intentar modificar el contenido del literal puede no desencadenar un error de tiempo de ejecución (incluso puede parecer que funciona según lo previsto). La definición del lenguaje C deja el comportamiento "indefinido" para que el compilador sea libre de manejar la situación como mejor le parezca.

En C ++, los literales de cadena se almacenan en matrices de const char, de modo que cualquier intento de modificar el contenido del literal desencadenará un diagnóstico en tiempo de compilación .

Como Christian señala, la palabra clave const no era originalmente una parte de C. Sin embargo, originalmente era parte de C ++, y hace que el uso de literales de cadena sea un poco más seguro.

Recuerde que la palabra clave const no significa "almacenar esto en la memoria de solo lectura", solo significa "esto puede no ser el objetivo de una tarea".

Recuerde también que, a menos que sea el operando de los operadores sizeof o unario *, o sea un literal de cadena utilizado para inicializar una matriz de caracteres en una declaración, una expresión de el tipo "matriz de elementos N de T" se convertirá ("decaimiento") en una expresión de tipo "puntero a T" y el valor de la expresión será la dirección del primer elemento de la matriz

En C ++, cuando escribes

const char *str = "Hello, world";

La dirección del primer carácter de la cadena se almacena en str. Puede configurar str para que apunte a un literal de cadena diferente :

str = "Goodbye cruel world";

Pero lo que no puede hacer es modificar el contenido de la cadena, algo así como

str[0] = 'h';

O

strcpy( str, "Something else" );
3
John Bode 4 may. 2020 a las 21:53

C inicialmente no tenía la palabra clave const, por lo que rompería el código heredado si cambiaban los literales para requerir const - calificación después de la introducción de la palabra clave. Sin embargo, los literales de cadena de C son inmutables, por lo que cambiar el contenido es un comportamiento indefinido incluso si no es const calificado.

C ++, por otro lado, fue diseñado con la palabra clave const. Inicialmente, C ++ permitió que los literales de cadena se asignaran a char * no calificados char * probablemente por compatibilidad con el código C existente. A partir del estándar C ++ 03, sin embargo, decidieron desaprobar esta funcionalidad en lugar de permitir que la disonancia continúe a perpetuidad. Supongo que la cantidad de código C ++ heredado que depende de const no calificado char * s que apunta a literales de cadena para ser lo suficientemente pequeño como para que sea una compensación digna.

8
Christian Gibbons 4 may. 2020 a las 21:45