Reputation: 21
Please see, I defined const int & a = 1
by reference, and forced the pointer to convert pa
to a
, and changed the value of a by changing pa
. This was successful.
But when const int k = 1
is defined and the above operation is repeated, although pk
and k
are the same address, * pk
and k
are not the same value.
What is the principle behind it?
Could you please explain how the IDE work with the memory allocation when I do so?
const int &a = 1;
int *pa = (int*)&a;
cout << &a << endl;
cout << pa << endl;
*pa = 2;
cout << a << endl;
//And here is the outcome.
//0x7ffeeb5d8a24
//0x7ffeeb5d8a24
//2
So here we changed a
successfully.
const int k = 1;
cout << &k << endl;
int *pk = (int*)&k;
cout << &k << endl;
cout << pk << endl;
*pk = 2;
cout << *pk << ' ' << k;
//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//2 1
//Process finished with exit code 0
*pk
andk
here have same address, but not the same value!
How could this happen?
Upvotes: 0
Views: 92
Reputation: 596582
This is technically undefined behavior. It is not safe to modify const
data at runtime, even if you cast away its const-ness. Only data that is initially non-const
and has const
added to it later can safely have that const
casted away.
But, to explain why you are seeing the output that is confusing you - the answer is compiler optimization!
The compiler sees const int k = 1;
as a compile-time constant and assumes k
will never change value (and rightly so!). When the compiler sees cout << *pk << ' ' << k;
, it is allowed to replace k
with the value 1
right there at the call site at compile-time, thus you are really executing cout << *pk << ' ' << 1;
regardless of what you do to k
at runtime. But, being that k
is a compile-time constant that you take the address of, it has to be stored in memory, and the compiler is free to (and likely will) store that value in read-only memory. Altering such memory at runtime is likely to crash your app, but that is not a guarantee.
Upvotes: 5