1

Possible Duplicate:
Modifying a const through a non-const pointer

I'm studying C++, and very interesting about pointers. And I tried to change value of a constant value (my teacher called it backdoor, please clarify if I'm wrong) like this:

const int i = 0;

const int* pi = &i;

int hackingAddress = (int)pi;
int *hackingPointer = (int*)pi;

*hackingPointer = 1;

cout << "Address:\t" << &i << "\t" << hackingPointer << endl;
cout << "Value:  \t" << i << "\t\t" << *hackingPointer << endl;

system("PAUSE");

return 0;

However, the result is very strange. Although the two addresses are the same, the values are different.

How is my code executed? And where is 0 and 1 value is stored exactly?

Community
  • 1
  • 1
Luke Vo
  • 17,859
  • 21
  • 105
  • 181
  • also, from earlier today: http://stackoverflow.com/questions/10792757/casting-a-const-int-to-a-pointer – Mankarse May 29 '12 at 10:54
  • @Mankarse Wow, maybe that's maybe my friend. We discuss this problem earlier, I don't know he posted on StackOverflow before me :) Should I vote a delete? – Luke Vo May 29 '12 at 11:03

3 Answers3

11

You've discovered a little thing that C++ developers call undefined behavior. You told the compiler that "i is a constant with the value 0". So when you ask the compiler for the value of i, it tells you that it is 0.

Mucking around with trying to change the value of a constant violates the assumptions made by the compiler (that constants are going to be, well, constant), and so, the compiler is going to generate invalid or inconsistent code.

There are a lot of situations in C++ where it is possible to do something without the compiler catching it as an error, but the result is undefined. And if you do that, then you get results like what you're seeing. The compiler does something weird and unexpected.

Oh, and if your teacher is trying to teach you anything from an example such as this, he's wrong, and you should be very scared.

The only guarantee you get from code like this is this:

the compiler can do literally anything it likes

When you write code, you have an implicit contract with the compiler:

"If I write well-defined C++ code, then you convert it into an executable with the same effects as described by the C++ standard".

When you do something like this, you violate the contract. And then the compiler isn't obliged to follow it either. If you give the compiler code that is not well-defined according to the C++ standard, then it can't, and isn't going to, create an executable which does as the C++ standard specifies.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • Thank you for your explanation. My teacher didn't teach this, I found this is interesting and tried myself, and when I asked him about this result, he also couldn't explain why. Anyway, I had a fun experience, and thank you for your clear explanation :) – Luke Vo May 29 '12 at 11:12
3

It seems, that compiler has optimized (inlined int const value)

cout << "Value:  \t" << i << "\t\t" << *hackingPointer << endl;

to

cout << "Value:  \t" << 0 << "\t\t" << *(0x0044ff28) << endl;

Anyway, you have still succeeded to change value of memory where i is stored. But do not try this at home :-)

Greg
  • 1,660
  • 13
  • 12
0

It is not permitted to change the values of a constant, in fact it's undefined behaviour so your program could do anything as a result.

In this instance it looks like your compiler optimised the read away at compile time because it knew the value is fixed. Lots of implementations might just crash when you try and change it, but you cannot and should not bet or rely upon the result of any undefined behaviour ever.

Flexo
  • 87,323
  • 22
  • 191
  • 272