Подтвердить что ты не робот

Изменение константы с помощью указателя не const

Я немного смущен, что произошло в следующем коде:


const int e = 2;

int* w = ( int* ) &e;          // (1) cast to remove const-ness
*w = 5;                        // (2)

cout &lt&lt *w &lt&lt endl;            // (3) outputs 5
cout &lt&lt e &lt&lt endl;             // (4) outputs 2

cout &lt&lt "w = " &lt&lt w &lt&lt endl;   // (5) w points to the address of e
cout &lt&lt "&e = " &lt&lt &e &lt&lt endl;

В (1) w указывает на адрес e. В (2) это значение было изменено на 5. Однако, когда отображались значения * w и e, их значения различны. Но если вы печатаете значение w pointer и & e, они имеют одинаковое значение/адрес.

Почему e все еще содержал 2, даже если он был изменен на 5? Сохранялись ли они в отдельном месте? Или временно? Но почему значение, указанное w, по-прежнему является адресом e?

4b9b3361

Ответ 1

Как я уже сказал в своем комментарии, как только вы изменили значение const, вы находитесь в состоянии w90 > , поэтому не имеет смысла говорить о том, что происходит. Но какого черта..

cout << *w << endl;            // (3) outputs 5
cout << e << endl;             // (4) outputs 2

При угадывании *w оценивается во время выполнения, но e рассматривается как постоянная времени компиляции

Ответ 2

Я подозреваю, что вы отключили компилятор. Он не ожидает, что вы сыграете грязные трюки с e, поэтому, когда он увидит линию:

cout << e << endl;

Он просто вставляет значение 2 вместо поиска фактического значения. Вы можете проверить (или опровергнуть) это, посмотрев на разборку вашей программы.

Ответ 3

Я предполагаю, что компилятор оптимизировал вывод значения. Он видит, что e является const (поэтому он не может измениться - теоретически) и изменяет cout << e << endl; на cout << 2 << endl;. Однако e все еще должен существовать, потому что он используется w, поэтому w правильно берет свой адрес и изменяет его значение, но вы не видите этого в cout.

Мораль истории - объявляйте вещи const, когда вы действительно хотите быть const. Отказ const не является хорошей идеей.

Ответ 4

Единственное, что я могу придумать, это компилятор, который каким-то образом оптимизировал код таким образом, что любые ссылки на e заменяются значением 2, хотя он присваивает память для e

так в силу (влияет?) строка в комментарии (4) "оптимизирована" как

cout << "2" << endln;

Ответ 5

Я думаю, что компилятор использует константу для оптимизации переменной и вставки фиксированного значения в код.

Ответ 6

Это описано в разделе [dcl.type.cv]/4 стандарта С++ 14 (предыдущие стандарты также имели аналогичный текст):

За исключением того, что любой член класса, объявленный mutable, может быть изменен, любая попытка изменить объект const во время его жизни приводит к поведению undefined.

e является объектом const, а *w = 5; пытается изменить этот объект, поэтому результат undefined.