Я читал, это не определено в некоторых стандартах C (возможно 99?) что происходит, когда const модифицируется. Но студент подарил мне некоторый код, который я модифицировал.
Я не вижу ничего особенного в адрес постоянной переменной a
, Я подтвердил, что &a
а также b
одинаковы, поэтому компилятор не указывает тонко на другое место.
Тем не менее, когда я назначаю *b
, Const значение не меняется.
Я не бегу с оптимизацией. Когда я собираю с -g
флаг для отладки и перехода в код, я получаю ожидаемые результаты (расположение переменной в памяти a
изменения). Тем не менее код, представленный ниже, не отражает обновленное значение a
,
Это то, что временные файлы теперь помещаются в регистры даже в режиме отладки, без оптимизации?
#include <iostream>
using namespace std;
int main(){
const int a = 15;
cout << a << '\n';
int * b= (int*)&a;
cout << &a << "\n";
cout << b << "\n";
*b = 20;
cout << *b << '\n';
cout << a << '\n';
int x = a;
cout << x << '\n';
x = *b;
cout << x << '\n';
return 1;
}
Это тоже неопределенное поведение в C ++ мы можем увидеть это, перейдя к черновому стандартному разделу C ++ 7.1.6.1
CV-квалификаторы параграф 4 который говорит:
[…] любая попытка изменить объект const в течение срока его службы (3.8) приводит к неопределенному поведению.
Неопределенное поведение означает, что результаты непредсказуемы, что фактически означает, что возможны любые результаты, даже те, которые на первый взгляд бросают вызов интуиции.
Быстрый эксперимент с godbolt с помощью -O0
поэтому оптимизация не происходит, показывает, что компилятор просто использует буквальное значение 15
за a
вместо того, чтобы извлечь его из памяти и распечатать это:
movl $15, %esi #,
Таким образом, компилятор выполняет постоянное складывание поскольку предполагается, что с a
является постоянным, он может просто использовать значение 15
где бы то ни было a
, Что вполне разумно, так как вы сказали это a
был постоянным.