Question

#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!

Was it helpful?

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.

OTHER TIPS

This is where you've gone astray:

int main() {
        const int a = 2;
        const int *p = &a;
        int *p2 = const_cast<int*>(p);
        *p2=5;

On the last line here, you've assigned a variable thu a pointer that points to something that is actually const. That is, a is const. p2 points to a. You can't change the value of a, even through p2, without invoking Undefined Behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top