Странное поведение с const_cast

Я знаю, что использование const_cast – это, как правило, плохая идея, но я играл с ней, и я наткнулся на странное поведение, где:

Два указателя имеют одинаковое значение адреса, но при де-ссылке дают разные значения данных.

У кого-нибудь есть объяснение?

Код

 #include  int main() { const int M = 10; int* MPtr = const_cast(&M); (*MPtr)++; std::cout << "MPtr = " << MPtr << " (*MPtr) = " << (*MPtr) << std::endl; std::cout << " &M = " << &M << " M = " << M << std::endl; } 

Вывод

 MPtr = 0x7fff9b4b6ce0 (*MPtr) = 11 &M = 0x7fff9b4b6ce0 M = 10 

Таким образом, помимо «неопределенного поведения» (который он есть), компилятор отлично справляется с тем, что M является константой, поэтому не будет изменяться при оценке cout ... << M << ... , поэтому можно использовать инструкцию, которая имеет непосредственное значение 10, вместо фактического значения, сохраненного в памяти M (Конечно, стандарт не скажет, как это работает, больше, чем «оно неопределено», а компиляторы могут выбирать разные решения в разных обстоятельствах и т. Д. И т. Д., Поэтому вполне возможно, что вы получите разные результаты, если вы измените код, использовать другой компилятор, другую версию компилятора или ветер дует в другом направлении).

Часть сложного бита с «неопределенным поведением» заключается в том, что он включает в себя вещи, которые «отлично, что вы можете ожидать», а также «почти то, что вы ожидаете». Компилятор также может решить начать тетрис, если он обнаружит, что это то, что вы делаете.

И да, это очень одна из причин, почему вы НЕ ДОЛЖНЫ использовать const_cast . По крайней мере, НЕ на вещах, которые первоначально были const - это нормально, если у вас есть что-то в этом роде:

 int x; void func(const int* p) { ... int *q = const_cast(p); *q = 7; } ... func(&x); 

В этом случае x не является фактически const, он просто становится const, когда мы передаем его func . Конечно, компилятор все же может предположить, что x не изменен в func , и, следовательно, у вас могут быть проблемы ....

Программа имеет неопределенный bahaviour, потому что вы не можете изменять объект const.

Из стандарта C ++

4 Некоторые другие операции описаны в этом Международном стандарте как неопределенные (например, эффект попытки изменения объекта const ). [Примечание. Этот международный стандарт не налагает никаких требований на поведение программ, которые содержат неопределенное поведение. -End note]

  • Когда следует использовать static_cast, dynamic_cast, const_cast и reinterpret_cast?
  • Арифметика указателей
  • Как направить себя в UnsafeMutablePointer type в swift
  • используя printf для печати плавающих значений
  • Возвращаемые массивы из функции в c ++
  • Указатель функций, отлитый от другой подписи
  • Является ли хорошей практикой NULL указатель после его удаления?
  • Используется для нескольких уровней разметки указателя?
  • Преобразование из производного ** в базу **
  • C Программирование: malloc () внутри другой функции
  • C указатель на двумерный массив
  • Давайте будем гением компьютера.