-2

I'm trying to change value of const variable via its address.

following this code:

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>

using namespace std;

int main(void)
{
    uint64_t const x = -1;
    uint64_t *b = reinterpret_cast<uint64_t*>(0x28ff10);
    cout<< x << endl;
    cout<< &x << " " << b << " " << *b << endl;
    printf("%p\n", &x);
    *b = 10;
    cout<< &x << " " << x << " " << b << " " << *b << " " << *(reinterpret_cast<uint64_t*>(0x28ff10)) <<endl;
    return 0;
}

Compiled with MinGW 4.8.1:

g++ -g main.cpp && ./a.exe

And this is output:

18446744073709551615
0x28ff10 0x28ff10 18446744073709551615
0028FF10
0x28ff10 18446744073709551615 0x28ff10 10 10

Could anyone explain it ?

EDIT: Figured out! compile still optimized my variable although I compiled it with -O0. Looked at ASM generated, I saw that printf and cout put directly the value instead of the variable symbol.

So, to make my code do right behavior, I have to declared it with volatile static

LongLT
  • 411
  • 6
  • 19
  • See also [How is a variable at the same address producing 2 different values?](http://stackoverflow.com/q/22656734/1708801) – Shafik Yaghmour May 07 '15 at 15:28
  • You will have to look at the assembly code that this generates to really understand what's going on here. Why aren't you doing: uint64_t *b = reinterpret_cast(&x); (You can also try a C cast, or const_cast). – grebulon May 07 '15 at 15:30
  • @grebulon: Why would you suggest that? – Lightness Races in Orbit May 07 '15 at 15:34
  • Just to see what happens. In any case, the standard specifies that this is undefined. It's interesting to see what the compiler is producing. I'd guess it's caching either x or b (or both) in registers. – grebulon May 07 '15 at 15:38
  • If the compiler needs to store a `const` at all then it's free to store it in a read-only section of the segment. That means the memory content is protected from modification by the CPU at run time. – Andy Brown May 07 '15 at 16:36
  • @LongLT - In the embedded world, unit tests (prior to hardware availability) often motivate a developer to modify a read-only (const) simulated (in ram) register. In that world, several techniques are available and widely used. I will try to submit a question (that you would recognize), then provide there the answer I was working on for you when this OP was terminated. But first, I must go read the referenced answers, and see if I can create a version that won't be shut down. – 2785528 May 07 '15 at 17:10
  • I believe that the problem which I'm facing is related with compiler specific. Most suitable way is debug in assembly like @grebulon said, I guess. But if you could provide a good answer, please do it. And more important, why almost people always talking about undefined behavior? just think my question is just for knowledge – LongLT May 08 '15 at 02:20
  • @LongLT - [http://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/] is my favorite article that addresses your question, and I think it is correct, specifically see the 3rd mcve the author presents. I think language nazi's would still declare undefined behavior, but I am more pragmatic (and seldom read the spec). I have found that so called 'undefined behavior' is NOT random behaviour. If it works once ... If you worry more about the language nazi's, you might consider adding an assert (that the value changes where you want it to). If it changes once, it will continue. – 2785528 May 11 '15 at 14:40

1 Answers1

5

I'm trying to change value of const variable via its address.

You've already gone wrong by this point.

const is short for "constant".

You cannot mutate a constant.

Sometimes you can get it to sort of look like you did, but doing so has undefined behaviour. You told your compiler that it can make all sorts of assumptions about x (including optimising it out from your binary entirely!) because you promise that you'll never change it. Then you change it.

No dinner for you tonight, says Mr. Compiler!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • hmm, I think that const is just the compiler's insurance, isn't it? – LongLT May 07 '15 at 15:27
  • @LongLT: The fact that you had to ask this question is proof otherwise. Yes, it's insurance from the compiler to the programmer ... _but it's also insurance from the programmer to the compiler_, and you broke it. – Lightness Races in Orbit May 07 '15 at 15:27
  • I'm not really understand what you say, but is there any ways to change value of const like I did above ? I think if exist an address, why I can't change value of that address – LongLT May 07 '15 at 15:31
  • Please re-read @LightnessRacesinOrbit's answer on why you **need to NOT do that**. It's undefined behavior (and also bad practice in general). – Ven May 07 '15 at 15:32
  • 2
    @LongLT: No, that's nonsense. In particular, and in practice, you're falling down at this assumption: "if exist an address". The compilation process is much, much, _much_ more complicated than you're giving it credit for. Anyway, as I said in my answer, `const` is short for "constant". You cannot change it. _That's what it means_. Why do you want to change a constant so much? Use a variable instead. That's what variables are for. – Lightness Races in Orbit May 07 '15 at 15:32