When I write this code fragment, after modifying the value of const variable i through pointer I am getting value of i as 10, but when i print *ptr i get 110.
const int i = 10;
int *ptr = const_cast<int *>(&i);
*ptr = *ptr + 100;
cout << "i: " << i << "\t*ptr: " << *ptr << endl;
I am getting output i: 10 and *ptr :110.
And in this case I am having a const variable x as a member variable of class Base. And through function show() I am able to modify the value of const variable x i.e when I print x and *ptr I get changed value in both.
class Base
{
public:
const int x;
Base(int i) : x(i) {}
virtual void show()
{
int *ptr = const_cast<int *>(&x);
int *ptr = const_cast<int *>(&x);
cout << "In Base show:\n";
cout << "Address of x : " << &x << endl;
cout << "Address in ptr : " << ptr << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
*ptr = *ptr + 10;
cout << "After modifying " << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
}
};
class Derived : public Base
{
public:
Derived(int i) : Base(i){}
virtual void show()
{
int *ptr = const_cast<int *>(&x);
cout << "In Derived show:\n";
cout << "Address of x : " << &x << endl;
cout << "Address in ptr : " << ptr << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
*ptr = *ptr + 10;
cout << "After modifying " << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
}
};
int main()
{
Base bobj(5),*bp;
Derived dobj(20), *dptr;
bp = &bobj;
bp->show();
bp = &dobj;
bp->show();
return 0;
}
The output which I am getting is this
In Base show:
Address of x : 0x7fff82697588
Address in ptr : 0x7fff82697588
value in x : 5
value in ptr : 5
After modifying
value in x : 15
value in ptr : 15
In Derived show:
Address of x : 0x7fff82697578
Address in ptr : 0x7fff82697578
value in x : 20
value in ptr : 20
After modifying
value in x : 30
value in ptr : 30
Can anybody help.
The reason is that your compiler has inlined the value of i
into the code when compiling this line:
cout << "i: " << i << "\t*ptr: " << *ptr << endl;
Because i
is a const
variable, the compiler has optimised the code by replacing i
in the above line with 10
. If we look at the generated assembly (I'm using VS2010):
002314F2 mov ecx,dword ptr [ptr] // ptr is being pushed here (110)
002314F5 mov edx,dword ptr [ecx]
002314F7 push edx
002314F8 push offset string "\t*ptr: " (23783Ch)
002314FD mov ebx,esp
002314FF push 0Ah // 0Ah is being pushed here (A is hex for 10)
00231501 push offset string "i: " (237830h)
What has happened is that you have modified the constant in memory, but the generated assembly doesn't actually use the memory address - it simply outputs '10' regardless of what's in memory.
As said by Kerrek, this is undefined behavior, so other compilers may do something completely different to this.
In general it is a bad idea to use const_cast
with few exceptions.