De hecho, "hello"
es de tipo char const[6]
.
Pero la esencia de la pregunta sigue siendo correcta: ¿por qué C++ nos permite asignar una ubicación de memoria de solo lectura a un tipo que no sea const
?
La única razón para esto es la compatibilidad con versiones anteriores del código C antiguo, que no sabía const
. Si C++ hubiera sido estricto aquí habría roto un montón de código existente.
Dicho esto, la mayoría de los compiladores se pueden configurar a advierten sobre el código como obsoleto, o incluso lo hacen de forma predeterminada. Además, C++ 11 no permite esto por completo, pero los compiladores pueden no aplicarlo todavía.
Para aficionados Standerdese:
[Ref 1]C++ 03 estándar: § 4.2/2
Una cadena literal (2.13.4) que no es una amplia el literal de cadena se puede convertir a un valor r de tipo "puntero a char"; un literal de cadena ancho se puede convertir a un valor r de tipo "puntero a wchar_t". En cualquier caso, el resultado es un puntero al primer elemento de la matriz. Esta conversión se considera solo cuando hay un tipo de destino de puntero apropiado explícito, y no cuando hay una necesidad general de convertir de un valor l a un valor r. [Nota: esta conversión está en desuso. Ver el Anexo D.] Con el propósito de clasificar en resolución de sobrecarga (13.3.3.1.1), esta conversión se considera una conversión de matriz a punta seguido por una conversión de calificación (4.4). [Ejemplo: "abc" se convierte en "puntero a const char" como una conversión de matriz a puntero, y luego a "puntero a char" como una conversión de calificación. ]
C++ 11 simplemente elimina la cita anterior que implica que es código ilegal en C++ 11.
[Ref 2]C99 estándar 6.4.5/5 "literales de cadena - Semántica":
En fase de traducción 7, un byte o código de valor cero se adjunta a cada carácter multibyte secuencia que resulta de una cadena literal o literales. La secuencia de caracteres multibyte se usa luego para inicializar una matriz de duración de almacenamiento estático y longitud suficiente para contener la secuencia.Para literales de cadena de caracteres, los elementos de la matriz tienen tipo char, y se inicializan con los bytes individuales de la secuencia de caracteres multibyte; para literales de cadena ancha, los elementos de matriz tienen el tipo wchar_t y se inicializan con la secuencia de caracteres anchos ...
No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores adecuados. Si el programa intenta modificar dicha matriz, el comportamiento no está definido.
Esto solo se permite para la compatibilidad con C. Generalmente en C++ se considera obsoleto y los buenos compiladores dan una advertencia. – iammilind