Два разных значения по одному и тому же адресу памяти

Код

#include <iostream>
using namespace std;

int main() {
    const int N = 22;
    int * pN = const_cast<int*>(&N);
    *pN = 33;
    cout << N << '\t' << &N << endl;
    cout << *pN << '\t' << pN << endl;
}

Выход

22 0x22ff74

33 0x22ff74

Почему существуют два разных значения по одному и тому же адресу?

Ответы

Ответ 1

Почему существуют две разные данные по одному и тому же адресу?

Нет. Компилятору разрешено оптимизировать любое упоминание о const, чтобы как бы вы указали его значение времени компиляции.

Обратите внимание, что компилятору также разрешено генерировать код, который стирает ваш жесткий диск при его запуске, если вы делаете неприятные трюки, такие как запись в память, зарезервированную для констант.

Ответ 2

Вы получаете поведение undefined в строке *pN = 33;, потому что вы изменяете значение const. Все может случиться. Не делайте этого.


Скорее всего, ваш компилятор просто оптимизирован. В строке:

cout << N << '\t' << &N << endl;

Он знает, что N является константным выражением со значением 22, поэтому просто меняет строку на:

cout << 22 << '\t' << &N << endl;

И на следующей строке вы получите значение по адресу N, которому вы "установили" значение 33. (Но на самом деле все, что вы сделали, это удалить любые гарантии о состоянии вашей программы.)

Ответ 3

Заявив, что N является const, вы пообещали, что не будете его изменять. И затем вы идете и модифицируете его. Это нарушает одно из предположений, которые делает компилятор, и в результате программа ведет себя некорректно.

Это называется "поведение undefined" - после нарушения предположения на языке поведение программы полностью undefined. Он не должен был производить этот вывод - он мог бы сделать 33 для обоих, или 42, или разбился, или стерт ваш жесткий диск, или вызвал демонов через ваши носовые проходы. Поэтому не изменяйте значения const:)

Ответ 4

int * pN = const_cast<int*>(&N);
*pN = 33;

Ваш код вызывает Undefined Behavior 1 потому что вы изменяете содержимое const квалифицированной переменной/объекта.

<суб > 1) Undefined Поведение: поведение, которое может возникнуть при использовании   ошибочной конструкцией программы или ошибочными данными, для которых   Стандарт не предъявляет никаких требований. [Примечание: допустимое поведение Undefined  варьируется от полного игнорирования ситуации с непредсказуемым   результатов, вести себя во время перевода или выполнения программы в   характерный для окружающей среды (с или без   выдача диагностического сообщения), до перевода перевода   или выполнение (с выдачей диагностического сообщения).

Ответ 5

const_cast в вашем коде, просто передайте указатель "Pn" на "N" , через который "N" можно изменить. Адрес "N" остается таким же, как передаваемый указатель "Pn"

Ответ 6

Вы можете объявить N как volatile, чтобы заставить компилятор извлекать текущее значение из местоположения переменной памяти.

volatile const int N = 22;