Search code examples
c++const-cast

C++ Does Const_Cast induce new variable?


#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;
}

Hi all!

According to the output, *p2 and a has different values, *p2 is 5 and a is 2.

However, p2 and &a are the same. I'm confused...

Could you please help me understand where this is the case?

Thank you very much!


Solution

  • 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.