Изменение константы с помощью указателя не const
Я немного смущен, что произошло в следующем коде:
const int e = 2;
int* w = ( int* ) &e; // (1) cast to remove const-ness
*w = 5; // (2)
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
cout << "w = " << w << endl; // (5) w points to the address of e
cout << "&e = " << &e << endl;
В (1) w указывает на адрес e. В (2) это значение было изменено на 5. Однако, когда отображались значения * w и e, их значения различны. Но если вы печатаете значение w pointer и & e, они имеют одинаковое значение/адрес.
Почему e все еще содержал 2, даже если он был изменен на 5? Сохранялись ли они в отдельном месте? Или временно? Но почему значение, указанное w, по-прежнему является адресом e?
Ответы
Ответ 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.