#include <iostream>
using namespace std;
int main() {
const int a = 2;
const int *p = &a;
int *p2 = const_cast<int*>(p);
*p2=5;
char *p3 = (char *)&a;
cout << "p2 is" << *p2 << endl;
cout << "p2 address " << p2 << endl;
cout << "a is " << a << endl;
cout << "a address " << &a << endl;
return 0;
}
大家好!
根据输出,* p2和a具有不同的值,* p2为5,a为2。
然而,p2和&amp; a是相同的。我很困惑......
你能帮我理解这种情况吗?
非常感谢!
答案 0 :(得分:6)
未定义的行为意味着任何事情都可能发生。包括这个。
7)[注意:根据对象的类型,通过指针,左值或指针进行写操作 从
const_cast
生成的数据成员转出const限定符 73 可能会产生未定义 行为(7.1.6.1)。 - 后注]
潜在的原因可能是编译器看到a
const
的方式,将cout << "a is " << a << endl;
优化为简单的cout << "a is " << 2 << endl;
。
例如,即使在调试版本中,我也会得到:
cout << "a is " << a << endl;
00CE1581 mov esi,esp
00CE1583 mov eax,dword ptr [__imp_std::endl (0CFD30Ch)]
00CE1588 push eax
00CE1589 mov edi,esp
//...
00CE158B push 2
//...
00CE158D push offset string "a is " (0CE7840h)
00CE1592 mov ecx,dword ptr [__imp_std::cout (0CFD308h)]
00CE1598 push ecx
00CE1599 call std::operator<<<std::char_traits<char> > (0CE1159h)
00CE159E add esp,8
00CE15A1 mov ecx,eax
00CE15A3 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0CFD304h)]
00CE15A9 cmp edi,esp
00CE15AB call @ILT+415(__RTC_CheckEsp) (0CE11A4h)
00CE15B0 mov ecx,eax
00CE15B2 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0CFD300h)]
00CE15B8 cmp esi,esp
00CE15BA call @ILT+415(__RTC_CheckEsp) (0CE11A4h)
我强调了重要部分 - 2
直接推送到operator<<
的参数堆栈,而不是正在读取的a
的值。
答案 1 :(得分:1)
这是你误入歧途的地方:
int main() {
const int a = 2;
const int *p = &a;
int *p2 = const_cast<int*>(p);
*p2=5;
在这里的最后一行,你已经指定了一个变量,一个指向实际上是const 的指针。也就是说,a
是const
。 p2
指向a
。即使通过a
,也无法在不调用未定义行为的情况下更改p2
的值。