未定義の動作とは、何でも起こり得ることを意味します。これも含めて。
5.2.11 定数キャスト [expr.const.cast]
const_cast
7) [ 注: オブジェクトの型に応じて、const 修飾子をキャストする73から生じるポインター、左辺値、またはデータ メンバーへのポインターを介した書き込み操作は、未定義の動作を生成する可能性があります (7.1.6.1)。—終わりのメモ]
根本的な理由は、コンパイラが の様子を見a
て、単純なconst
に最適化することである可能性があります。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