让我们先查看下面的代码。非常简短的代码:
int main()
{
const int n=9;
int *p=(int*)&n;
*p=5;
cout<<*p<<endl; //result is 5
cout<<n<<endl; // 9
int a=n+1;
cout<<a<<endl; // 10
}
令我惊讶的是,编译器根本没有抱怨。结果就像我所说的评论一样
但是,如果这或多或少都有意义。更令人惊讶的是,
当你调试它时,你可以看到n的值实际上已经变为5!
但是,当你使用“n”时,似乎“n”仍然被视为原始值9!
所以我猜编译器已将“n”的原始值存储在其他地方,对吧?
那么现在存储的“n”的原始值是9,它是什么?
谢谢你的帮助!
答案 0 :(得分:3)
这可能是由于优化。由于您声明const int n=9
,因此您基本上承诺不会修改n
。因此编译器可以自由地将cout << n << endl;
优化为简单的cout << 9 << endl;
。我不认为旧值存储在其他地方。
然而,这是未定义的行为。
我可以确认这种行为的原因是优化,即使在调试版本中也是如此:
cout<<n<<endl;
01151426 mov esi,esp
01151428 mov eax,dword ptr [__imp_std::endl (11582B4h)]
0115142D push eax
0115142E mov edi,esp
//HERE:
//
01151430 push 9
//
//
01151432 mov ecx,dword ptr [__imp_std::cout (11582B0h)]
01151438 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11582ACh)]
0115143E cmp edi,esp
01151440 call @ILT+325(__RTC_CheckEsp) (115114Ah)
01151445 mov ecx,eax
01151447 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (11582A8h)]
0115144D cmp esi,esp
0115144F call @ILT+325(__RTC_CheckEsp) (115114Ah)
n
甚至没有进行讨论。
如果n
不是const
,则优化将是非法的:
00D51426 mov esi,esp
00D51428 mov eax,dword ptr [__imp_std::endl (0D582B4h)]
00D5142D push eax
00D5142E mov edi,esp
//HERE
//
00D51430 mov ecx,dword ptr [n]
00D51433 push ecx
//
//
00D51434 mov ecx,dword ptr [__imp_std::cout (0D582B0h)]
00D5143A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0D582ACh)]
00D51440 cmp edi,esp
00D51442 call @ILT+325(__RTC_CheckEsp) (0D5114Ah)
00D51447 mov ecx,eax
00D51449 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0D582A8h)]
00D5144F cmp esi,esp
00D51451 call @ILT+325(__RTC_CheckEsp) (0D5114Ah)
这里,n
的值被推到参数堆栈上,因为它不是const
。