Where is the hidden storage?

I am a little confused in 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 address : %u\n", &c); printf("P is pointing to : %u\n", p); 

What outputs are executed below when executing

 c = C *p = K c address : 3221180271 P is pointing to : 3221180271 

Here I can notice that both "& c" and "p" have the same address in memory.

Then what is the hidden mechanism by which "p" is able to store a different value than "c", while both have the same address space in memory?

+4
source share
4 answers

There is no "hidden storage". These lines

 const char c = 'C'; char * p = const_cast<char *>(&c); // NO! 

seriously violate const correctness . You are creating a non const pointer to what const was originally. Never do that. . Although the translation itself is fine, if you try to dereference p , it will cause undefined behavior, which means that something can happen, including the behavior that you just described.

Speaking of what happens, the compiler adds the constant c to print the first cout c statement. Therefore, the compiler probably included the following cout expressions in it:

 cout << " c = " << 'C' << endl; // Note literal 'C' instead of variable c cout << " *p = " << *p << endl; 

So, while the second cout operator reflects the new value of c by dereferencing p , the first cout operator has no effect.

The first cout not affected, because the compiler assumed that the value of c would never change (this is const anyway). Based on this assumption, the compiler replaced access to the variable with the constant value itself.

You violated the compiler assumption when you did this:

 *p = 'K'; // NO! 

since p points to the constant c , and you just changed it to K , giving you the behavior you see.

+11
source
 const char c = 'C'; char * p = const_cast<char *>(&c); *p = 'K'; 

This behavior is undefined. If the object is originally const , you cannot write it, even after const_cast . It doesnโ€™t really help to understand what and how the code does when you are in the undefined behavior area.

+5
source

Others explained that this behavior is undefined. What probably happens behind the scenes is that the compiler notes that c is a constant, so it allows you to cache its value in the register. When you later read the value of c to print it, the compiler does not bother to extract it from memory (it is const , so it cannot be changed, right?), But instead uses a cached value.

+1
source

Undefined. The compiler is allowed to optimize (for example, store in the register) things that he knows are immutable.

There is little chance that char volatile marking will cause the compiler to respond in a more expected way. Keep in mind that still undefined behavior

+1
source

Source: https://habr.com/ru/post/1369128/


All Articles