const_cast объясните почему одинаковые адреса но значения разные

const_cast снимающий нижнюю константность не изменяет исходный объект, с этим вопросов нет. Вопрос именно в другом:

const int i = 123;
const int* pci = &i;
int* pi = const_cast<int*>(pci);
cout << "i&:\t" << pci <<  " " << i << "\npci\t" << pci << " " << *pci << "\npi\t" << pi << " " << *pi << "\n***********" << endl;
*pi = 55;
cout << "i&:\t" << pci <<  " " << i << "\npci\t" << pci << " " << *pci << "\npi\t" << pi << " " << *pi << "\n***********" << endl;
*(const_cast<int*>(&i)) = 888;
cout << "i&:\t" << pci <<  " " << i << "\npci\t" << pci << " " << *pci << "\npi\t" << pi << " " << *pi << "\n***********" << endl;

почему адреса исходного объекта, а так же двух указателей совпадают, хотя в них лежат разные значения? Изначально Я думал что адреса будут одинаковыми пока мы не изменим значение через const_cast или через указатель на не константу, но как видно из результата работы программы, обращение идёт по одному адресу.


Ответы (1 шт):

Автор решения: Harry

Не пойму, что удивляет? Все указатели — что pci, что pi — указывают на i, и равны &i. Это к первому столбцу вывода. Где все адреса одинаковы.

Второй столбец: при выводе i компилятор ориентируется на то, что это константа, и выводит именно константу, а не значение переменной. Готов спорить, что при просмотре сгенерированного кода там не будет никакого обращения к памяти.

А два последних значения получаются через разыменование.

Только вот несмотря на то, что мы получаем указатель на неконстантную величину при применении const_cast, менять ее категорически не следует! Не для этой цели const_cast придумали...

P.S. Вот, посмотрите: https://godbolt.org/z/d17a6EWY6

Как видите, после всех изменений значений по адресу все равно получаем при выводе:

mov     esi, 123
mov     rdi, rax
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

т.е. он просто выводит 123, не интересуясь, что там на самом деле в переменной записано.

→ Ссылка