Весь ответ, вероятно, будет говорить о "неопределенном поведении", так как вы пытаетесь логически бессмысленно изменить константу.
Хотя это технически идеально, позвольте мне дать вам несколько советов о том, почему это происходит (о«как», см. «Мистический ответ»).
Это происходит потому, что C ++ является по замыслу" несовершенно заданным языком ".«Несовершенство» заключается в ряде «неопределенных поведений», которые пронизывают спецификацию языка.
Фактически, разработчики языка сознательно выбирают, что при некоторых обстоятельствах вместо того, чтобы сказать «если вы это сделаете, вам дадутчто ", (это может быть: у вас есть этот код или у вас есть эта ошибка) они предпочитают говорить" мы не определяем, что произойдет ".
Это позволяет производителям компиляторов свободно решать, что делать.делать.И поскольку на многих платформах работает много компиляторов, может быть оптимальным решением для одного не обязательно оптимальное решение для другого (которое может полагаться на машину с другим набором команд), и, следовательно, вы (как программист) осталисьв драматической ситуации, когда вы никогда не будете знать, чего ожидать, и даже если вы тестируете его, вы не можете доверять результату теста, поскольку в другой ситуации (компиляция того же кода с помощью другого компилятора или просто другой его версии)или для другой платформы) все будет иначе.
«Плохая» вещь в данном случае заключается в том, что компилятор должен предупреждать, когда происходит неопределенное поведение (, заставляяconst следует предупреждать как потенциальную ошибку, особенно, если компилятор выполняет константные оптимизации , так как это бессмыслица, если const разрешено изменять), как это, скорее всего, происходит, есливы указываете правильный флаг (может быть -W4 или -wall или -pedantic или аналогичный, в зависимости от вашего компилятора).
В частности, строка
int *ptr = (int *) &i;
должна выдавать предупреждение вроде: warning: removing cv-qualifier from &i.
, чтобы, если вы исправили свою программу как
const int *ptr = (const int *) &i;
, чтобы удовлетворить предупреждение, вы получите ошибку в
*ptr = 99;
как error: *ptr is const
, что делает проблему очевидной.
Моральstory :
С юридической точки зрения, вы написали плохой код, поскольку он - по определению языка - полагается на неопределенное поведение.
От моральная точка зрения: компилятор вел несправедливое поведение: выполнение константного встраивания (замена cout << i
на cout << 5
) после принятия (int*)&i
является само-противоречием и бессвязнымповедение должно быть, по крайней мере, предупреждено.Если он хочет сделать одну вещь, он не должен принимать другую, или наоборот.
Поэтому проверьте, есть ли флаг, который можно установить для предупреждения, и , если нет , сообщите об этомпроизводитель компилятора - несправедливость: он не предупредил о собственном противоречии.