There was a thread about this a few months ago. I can summarize its contents to this simple statement: Do
not cast pointers to constants to pointers to variables.
On line 5, you're telling the compiler "I promise the value of x will never change from 99". The compiler can then use x as a symbolic constant, and instead of using a run time variable, it will evaluate x at compile time and replace it with 99. These two lines generate the exact same code:
1 2
|
std::cout <<x;
std::cout <<99;
|
(Note: The compiler may not actually do this. This is one possible optimization that the compiler may or may not implement. However, the compiler I'm talking about is known to do this.)
When you do &x, the compiler is forced to allocate a run time variable, because it's not possible to get the address of literal constants. The type of &x is 'const int *'. This is so the compiler won't let you do something like
*&x=10;
. However, the variable itself, like all data, can be modified. If you cast the pointer to (int *), the compiler will now let you modify the variable. It's possible to do
*(int *)&x=10;
.
However, this is a breach of the promise you made on line 5. You're modifying a variable you told the compiler would never change. The compiler isn't aware of this change because you're making it through a dereferenced pointer, and it will still understand a direct reference to 'x' as meaning '99'.
This is what causes the situation where (x!=*&x).
Pointers to constants exist so that the compiler can keep you from changing things you shouldn't. If you then go and strip this information, the compiler can no longer keep you from shooting yourself in the foot.