Почему два объекта const int имеют одинаковый адрес, но не одинаковое значение после преобразования "const"? - PullRequest
0 голосов
/ 25 марта 2020

Пожалуйста, смотрите, я определил const int & a = 1 ссылкой, и заставил указатель преобразовать pa в a, и изменил значение a, изменив pa. Это было успешно.

Но когда определено const int k = 1 и вышеуказанная операция повторяется, хотя pk и k - это один и тот же адрес, * pk и k - это не одно и то же значение.

Какой принцип стоит за этим?

Не могли бы вы объяснить, как IDE работает с распределением памяти, когда я это делаю?

const int &a = 1;
    int *pa = (int*)&a;
    cout << &a << endl;
    cout << pa << endl;
    *pa = 2;
    cout << a << endl;
//And here is the outcome.


//0x7ffeeb5d8a24
//0x7ffeeb5d8a24
//2

Итак, мы изменились a успешно.


    const int k = 1;
    cout << &k << endl;
    int *pk = (int*)&k;
    cout << &k << endl;
    cout << pk << endl;
    *pk = 2;
    cout << *pk << ' ' << k;

//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//2 1
//Process finished with exit code 0

*pk и k здесь имеют одинаковый адрес, но не одно и то же значение! Как это могло случиться?

1 Ответ

4 голосов
/ 25 марта 2020

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

Но, чтобы объяснить, почему вы видите вывод, который вас смущает - ответ оптимизация компилятора !

Компилятор видит const int k = 1; как постоянную времени компиляции и предполагает, что k никогда не изменит значение (и это правильно! ). Когда компилятор видит cout << *pk << ' ' << k;, ему разрешается заменить k значением 1 прямо на сайте вызова во время компиляции , таким образом, вы действительно выполняете cout << *pk << ' ' << 1; независимо от того, что вы делаете k во время выполнения . Но поскольку k является константой времени компиляции, адрес которой вы берете, она должна храниться в памяти, и компилятор может (и, вероятно, будет) сохранять это значение в постоянной памяти. Изменение такой памяти во время выполнения может привести к взлому sh вашего приложения, но это не гарантия .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...