C++ Does Const_Cast induce new variable? [duplicate]
-
09-07-2021 - |
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!
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.