This question already has an answer here:
-
Two different values at the same memory address
6 answers
Consider this :
#include <iostream>
using namespace std;
int main(void)
{
const int a1 = 40;
const int* b1 = &a1;
char* c1 = (char *)(b1);
*c1 = \'A\';
int *t = (int*)c1;
cout << a1 << \" \" << *t << endl;
cout << &a1 << \" \" << t << endl;
return 0;
}
The output for this is :
40 65
0xbfacbe8c 0xbfacbe8c
This almost seems impossible to me unless compiler is making optimizations. How ?
This is undefined behavior, you are modifying a const variable so you can have no expectation as to the results. We can see this by going to the draft C++ standard section 7.1.6.1
The cv-qualifiers paragraph 4 which says:
[...]any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.
and even provides an example:
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
In the standard definition of undefined behaviour in section 1.3.24
, gives the following possible behaviors:
[...] Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). [...]
Your code has undefined behaviour, because you are modifying a constant object. Anything could happen, nothing is impossible.
When you qualify them variables const
the compiler can assume a few things and generate code, this works fine providing you respect that agreement and not break it. When you\'ve broken it, you\'ll get undefined behaviour.
Note that when const
is removed, it works as expected; here\'s a live example.
As has been explained by others, modifying a const
value results in undefined behavior and nothing more needs to be said - any result is possible, including complete nonsense or a crash.
If you\'re curious as to how this particular result came about, it\'s almost certainly due to optimization. Since you defined a
to be const
, the compiler is free to substitute the value 40
that you assigned to it whenever it wants; after all, its value can\'t change, right? This is useful when you\'re using a
to define the size of an array for example. Even in gcc, which has an extension for variable-sized arrays, it\'s simpler for the compiler to allocate a constant-size array. Once the optimization exists it\'s probably applied consistently.