Where is the hidden storage?
I am little confused over the following situation
const char c = 'C';
char * p = const_cast<char *>(&c);
*p = 'K';
cout << " c = " << c << endl;
cout <<开发者_开发技巧 " *p = " << *p << endl;
printf("c's address : %u\n", &c);
printf("P is pointing to : %u\n", p);
Which outputs as below on execution
c = C
*p = K
c's address : 3221180271
P is pointing to : 3221180271
Here I can observe that both '&c' and 'p' having the same address in the memory.
Then what is the hidden mechanism by which 'p' is capable of storing a different value than 'c' is storing whereas both share the same address space in the memory?
There is no "hidden storage". These lines
const char c = 'C';
char * p = const_cast<char *>(&c); // NO!
seriously violate const
-correctness. You're creating a non-const
pointer to something that is originally const
. Do not do that ever. While the cast itself is fine, if you attempt to dereference p
it'll invoke undefined behavior, meaning anything can happen, including the behavior you've just described.
That being said, what's going on is that the compiler is folding the constant c
so that the first cout
statement prints out C
. So the compiler probably turned the cout
statements into these:
cout << " c = " << 'C' << endl; // Note literal 'C' instead of variable c
cout << " *p = " << *p << endl;
So while the second cout
statement reflects the new value of c
by dereferencing p
, the first cout
statement isn't affected.
The first cout
wasn't affected because the compiler assumed that the value of c
will never change (it is const
after all). With that assumption the compiler replaced the variable access with the constant value itself.
You've violated the compiler's assumption when you did this:
*p = 'K'; // NO!
since p
points to the constant c
and you've just changed it to K
, giving you the behavior you're seeing.
const char c = 'C';
char * p = const_cast<char *>(&c);
*p = 'K';
This is undefined behaviour. If an object is originally const
you cannot write to it, even after const_cast
. It doesn't help much to reason about what and how the code does something when you are in the realm of undefined behaviour.
Others have explained that this is undefined behaviour. What's probably happening behind the scenes is that the compiler spots that c
is const, so allows its value to be cached in a register. When you later read the value of c
to print it out, the compiler doesn't bother fetching it from memory (it's const
, so it can't have changed, right?), but just uses the cached value instead.
Undefined behaviour. The compiler is allowed to optimize (e.g. keep in a register) things that it knows are immutable.
There is a slight chance that marking the char volatile
would make the compiler respond more in expected fashion. Keep in mind that it is still undefined behaviour nonetheless
精彩评论