Undefined behavior means that anything can happen. Including this.
5.2.11 Const cast [expr.const.cast]
7) [ Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer
to data member resulting from a const_cast
that casts away a const-qualifier73 may produce undefined
behavior (7.1.6.1). —end note ]
The underlying reason might be that the compiler, seeing how a
is const
, optimizes cout << "a is " << a << endl;
to a simple cout << "a is " << 2 << endl;
.
For example, even in a debug build, I get:
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)
I highlighted the essential part - 2
is pushed directly on the argument stack of operator<<
, instead of the value of a
being read.