El problema es que está intentando modificar un literal de cadena. Si lo hace, el comportamiento de su programa no estará definido.
Decir que no se permite modificar una cadena literal es una simplificación excesiva. Decir que los literales de cadena son const
es incorrecto; Ellos no están.
ADVERTENCIA: Digression follows.
La cadena literal "this is a test"
es de una expresión del tipo char[15]
(14 para la longitud, más 1 para la terminación '\0'
).En la mayoría de los contextos, incluido este, dicha expresión se convierte implícitamente en un puntero al primer elemento de la matriz, del tipo char*
.
El comportamiento de intentar modificar la matriz a la que hace referencia una cadena literal no está definido, no porque sea const
(no lo es), sino porque el estándar C especifica que no está definido.
Algunos compiladores pueden permitirle salirse con la suya. Su código podría modificar realmente la matriz estática correspondiente al literal (lo que podría causar una gran confusión más adelante).
La mayoría de los compiladores modernos, sin embargo, almacenan la matriz en la memoria de solo lectura, no en la ROM física, sino en una región de la memoria que está protegida contra modificaciones por el sistema de memoria virtual. El resultado de intentar modificar dicha memoria suele ser una falla de segmentación y un bloqueo del programa.
¿Por qué no son literales de cadena const
? Como realmente no deberías tratar de modificarlos, ciertamente tendría sentido, y C++ sí hace literales de cadena const
. La razón es histórica. La palabra clave const
no existía antes de que fuera introducida por el estándar ANSI C de 1989 (aunque fue probablemente implementado por algunos compiladores antes de eso). Así, un programa pre-ANSI podría tener este aspecto:
#include <stdio.h>
print_string(s)
char *s;
{
printf("%s\n", s);
}
main()
{
print_string("Hello, world");
}
No había manera de hacer cumplir el hecho de que print_string
no está permitido modificar la cadena apuntada por s
. Hacer cadenas literales const
en ANSI C habría roto el código existente, lo que el comité ANSI C intentó evitar. No ha habido una buena oportunidad desde entonces para hacer un cambio en el lenguaje. (Los diseñadores de C++, en su mayoría Bjarne Stroustrup, no estaban tan preocupados por la compatibilidad con versiones anteriores) C.
Dude - "this is a test" es STRING LITERAL. Lo que significa que es un * LEA SOLAMENTE * "array of char". Incluso puede salirse con la suya tratando de modificarlo sin fallar en ciertas plataformas. Pero definitivamente es un no-no en * ANY * plataforma :) – paulsm4