Stackewinner, el puntero debe ser constante por que el estándar lo dice, punto. No puedes modificar una cadena de bajo nivel. Punto.
Ahora, ¿por qué el estándar es tan tajante? ¿Por qué tantos "puntos"? Bueno, tiene un motivo relacionado con cómo se implementan tales cadenas.
Un ejecutable, cuando se coloca en memoria, está divido en varias secciones: una es la sección de código (la famosa `.text` en ensamblador), que es donde va el código de la aplicación. Luego dispone de una pila (variables locales, el
stack), y un montículo (variables dinámicas -malloc y demás, el
heap). Luego hay dos secciones más (que no recuerdo sus nombres), donde van las variables globales inicializadas, y otra donde van las variables globales sin inicializar. El lugar donde van las variables globales sin inicializar es una sección que se inicializa a cero al comenzar el programa (o al menos en Linux; creo que si un SO dado no se divide en tales secciones, el compilador está obligado a inicializar a cero dichas variables globales para emular el comportamiento).
Y por último, está la sección `.rodata`. Ahí es donde van todas las variables globales constantes, y los
literales de cadena (es decir, toda cadena de bajo nivel que escribas en tu código fuente irá a esa sección). Si intentas modificar dicha sección (dado que es constante), a través de un puntero por ejemplo, se producirá
segmentation fault y el programa se cerrará.
Y por ese motivo, las cadenas son constantes por defecto (`char const*`), porque no se pueden modificar, al estar dentro de la sección constante de tu programa, y que está protegida por el sistema operativo. Si intentas hacerte el listo y modificarlas sí o sí:
char const* str = "cadena de bajo nivel";
void* str_void = str;
char* str = (char*)str_void;
str[1] = 'A';
Ocurrirá lo que he dicho antes,
segmentation fault.