开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜