Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to change value of a constant variable via reinterpret_cast?

all. I have read a code snippet from a book where the author tries to set the value of a register via direct memory access (he simulates this process). He used reinterpret_cast<volatile uint8_t*> for this. So, after reading his code, out of curiosity I have tried to apply the same code for a constant variable, and I experienced a very interesting output. I inserted the code below which is very simple:

int main()
{
  const std::uint8_t a = 5;
  
  const std::uintptr_t address = reinterpret_cast<std::uintptr_t>(&a);
  
  *reinterpret_cast<volatile uint8_t*>(address) = 10;
  
  std::cout << unsigned(a) << std::endl;

  return 0;
}

So, my purpose is to change the value of constant variable via direct memory access. I have written this code in Visual Studio C++ 2019 and compiled and run it. There was no any error or warning, but the output was very interesting. The value of a is printed as 5. So, I switched to the debug mode in order to see at each step what is happening. I will insert the images below:

Step 1
enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Step 2
enter image description here

Step 3
enter image description here

Step 4
enter image description here

Step 5
enter image description here

I am sorry to include debugging output as images, but I thought that it would be better to include images, so I will not miss any important detail. The thing that is interesting for me, how the program output is 5, while debugger clearly indicates the value of a is 10? (I even printed the addresses of a before and after the reinterpret_cast and they were the same.) Thank you very much.

>Solution :

The thing that is interesting for me, how the program output is 5, while debugger clearly indicates the value of a is 10?

This depends entirely on the compiler. It could output 10, 5, crash, … because it is undefined behavior.

If you want to know why the output of the binary created by a particular compiler has a certain result for undefined behavior, you have to look at the generated output of the compiler. This can be done using e.g. godbolt.org

For your code the output gcc (11.2) generates is:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     BYTE PTR [rbp-9], 5
        lea     rax, [rbp-9]
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        mov     BYTE PTR [rax], 10
        mov     esi, 5
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)
        mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     rdi, rax
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        mov     eax, 0
        leave
        ret

Here you can see that the compiler correctly assumes that the value of a will not change. And replaces std::cout << unsigned(a) << std::endl; with std::cout << unsigned(5) << std::endl;:

        mov     esi, 5
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)

If you remove the const from a the output is:

        movzx   eax, BYTE PTR [rbp-9]
        movzx   eax, al
        mov     esi, eax
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading