未定义的行为意味着任何事情都可能发生。包括这个。
5.2.11 常量转换 [expr.const.cast]
7) [注意:根据对象的类型,通过指针、左值或指向数据成员的指针的写操作由const_cast
丢弃 const 限定符73可能产生未定义的行为 (7.1.6.1)。——尾注]
根本原因可能是编译器在查看a
isconst
后优化cout << "a is " << a << endl;
为简单的cout << "a is " << 2 << endl;
.
例如,即使在 debug build中,我也得到:
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
被读取的值。