Я балуюсь с C++, читаю книги о хороших привычках на этом языке. Я читал про const_cast
и написал простую программу, которая отвечает на вопрос: можно ли убрать префикс const
и записать значение по этому адресу?
Мой код:
#include <iostream>
#include <iomanip>
int main ()
{
const int a = 5;
std::cout << std::hex << "&a = " << std::showbase << std::setfill('0') << &a << "\n";
int * b = const_cast<int *> (&a);
std::cout << std::hex << std::setfill('0') << "b = " << b << "\n";
std::cout << "Writing to address of a ..." << "\n";
*b = 10;
std::cout << "&a == b ? : " << ((&a == b) ? "True" : "False") << std::endl;
std::cout << a << std::endl;
std::cout << *b << std::endl;
return 0;
}
Выход :
00:35|domin568[35] ~/Desktop/experiments/newcpp $ ./const
&a = 0x7ffee465c528
b = 0x7ffee465c528
Writing to address of a ...
&a == b ? : True
0x5
0xa
Эта ситуация меня заинтересовала, они работают по одному и тому же адресу, но имеют разные значения? Давайте отладим его с помощью lldb!
00:37|domin568[39] ~/Desktop/experiments/newcpp $ lldb const
(lldb) b const.cpp:11
...
(lldb) r
Process 32578 launched: '/Users/domin568/Desktop/experiments/newcpp/const' (x86_64)
&a = 0x7ffeefbff478
b = 0x7ffeefbff478
Writing to address of a ...
Process 32578 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000dcb const`main at const.cpp:11
8 int * b = const_cast<int *> (&a);
9 std::cout << std::hex << std::setfill('0') << "b = " << b << "\n";
10 std::cout << "Writing to address of a ..." << "\n";
-> 11 *b = 10;
12 std::cout << "&a == b ? : " << ((&a == b) ? "True" : "False") << std::endl;
13 std::cout << a << std::endl;
14 std::cout << *b << std::endl;
Target 0: (const) stopped.
(lldb) p *b
(int) $0 = 5
(lldb) p b
(int *) $1 = 0x00007ffeefbff478
(lldb) p a
(const int) $2 = 5
(lldb) p &a
(const int *) $3 = 0x00007ffeefbff478
(lldb) s
Process 32578 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100000dd8 const`main at const.cpp:12
9 std::cout << std::hex << std::setfill('0') << "b = " << b << "\n";
10 std::cout << "Writing to address of a ..." << "\n";
11 *b = 10;
-> 12 std::cout << "&a == b ? : " << ((&a == b) ? "True" : "False") << std::endl;
13 std::cout << a << std::endl;
14 std::cout << *b << std::endl;
15 return 0;
Target 0: (const) stopped.
(lldb) p *b
(int) $4 = 10
(lldb) p *a
error: indirection requires pointer operand ('int' invalid)
(lldb) p a
(const int) $5 = 10
(lldb) s
&a == b ? : True
Process 32578 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100000e34 const`main at const.cpp:13
10 std::cout << "Writing to address of a ..." << "\n";
11 *b = 10;
12 std::cout << "&a == b ? : " << ((&a == b) ? "True" : "False") << std::endl;
-> 13 std::cout << a << std::endl;
14 std::cout << *b << std::endl;
15 return 0;
16 }
Target 0: (const) stopped.
(lldb) s
0x5 <---- wtf ? changed runtime ?
Может ли кто-нибудь объяснить мне, что стоит за сценой? Я знаю, что это, вероятно, неопределенное поведение, но почему оно так себя ведет?
Заранее спасибо !