Reputation: 154
int main() {
const int i =10;
int *j = const_cast<int*>(&i);
cout<<endl<<"address of i "<<&i;
cout<<endl<<"value of j "<<j;
(*j)++;
cout<<endl<<"value of *j "<<*j;
cout<<endl<<"value of i "<<i;
// If Not use Const //
int k = 10;
int *p = &k;
cout<<endl<<"address of k "<<&i;
cout<<endl<<"address of p "<<&p;
(*p)++;
cout<<endl<<"value of *p "<<*p;
cout<<endl<<"value of k "<<k<<endl;
}
Output is :
address of
i
0xbf8267d0
value ofj
0xbf8267d0
value of*j
11
value ofi
10
address ofk
0xbf8267d0
address ofp
0xbf8267c8
value of*p
11
value ofk
11
Can someone please explain why at the 3rd and 4th line of output
*j is 11
and i is 10
.
Why is i
also not 11?
Upvotes: 0
Views: 90
Reputation: 171127
The explanation is simple: Undefined Behaviour is undefined. When you use const_cast
to cast away constness of an object which was actually declared const
and then modify it, your program exhibits Undefined Behaviour and it can do literally anything. It can do what you expect, do something you don't expect, it can order pizza online.
In your particular case, the compiler probably optimised all uses of i
by replacing it with the literal 10
(because i
is const
, so its value cannot ever change in any way).
At the same time, i
was probably not placed in a read-only part of memory (otherwise, you'd get a crash on (*j)++
), and since j
is a pointer to int
(and not to const int
), reading from *j
cannot be optimised away and so the value actually stored in *j
(which is the storage of i
) is printed.
But the above is just speculation, really. The actual reason could be anything. A program with Undefined Behaviour is simply wrong and nothing can be predicted about its behaviour.
Upvotes: 4
Reputation: 36802
The compiler can assume that a const variable in such a situation won't be modified. It can take steps to generate more efficient code. In your example since i
is declared to be const
the compiler replaces the std::cout << i
with (effectively) std::cout << 10
Casting away the constness results in undefined behavior, so nothing is actually guaranteed to happen.
Consider something similar
const int i = 5;
// ...
if (i > 10) { // impossible!
std::cout << "hello world!";
}
In the above, an optimizing compiler can, at compile time, figure out that the constant 5
can't possibly be greater than 10
, so it will drop the if check and the body, if you looked into the assembly, you wouldn't even see the "hello world!"
string because it would have been optimized away and thrown out! Even if you replaced the ...
with a const_cast
and modified the value of i
that doesn't change the optimization that the compiler is allowed to perform assuming i
doesn't change.
Upvotes: 6