Это неопределенное поведение. Доказательство:
/* program.c */
int main()
{
const int a = 12;
int* p;
p = &a;
*p = 70;
printf("%d\n", a);
return 0;
}
gcc program.c
и запустите его. Выход будет равен 70 (gcc 4.3)
Затем скомпилируйте его следующим образом:
gcc -O2 program.c
и запустите его. Выход будет 12. Когда он выполняет оптимизацию, компилятор предположительно загружает 12 в регистр и не утруждает себя повторной загрузкой, когда ему нужно получить доступ к a для printf, потому что он «знает», что не может измениться.