Why can't assign const initialize while compile by pointer

Viewed 132

I'm curious about why my research result is strange

#include <iostream>

int test()
{
    return 0;
}

int main()
{
    /*include either the next line or the one after*/
    const int a = test(); //the result is 1:1
    const int a = 0; //the result is 0:1

    int* ra = (int*)((void*)&a);
    *ra = 1;
    std::cout << a << ":" << *ra << std::endl;
    return 0;
}

why the constant var initialize while runtime can completely change, but initialize while compile will only changes pointer's var?

2 Answers

The function isn't really that relevant here. In principle you could get same output (0:1) for this code:

int main() {
    const int a = 0;
    int* ra = (int*)((void*)&a);
    *ra = 1;
    std::cout << a << ":" << *ra;
}

a is a const int not an int. You can do all sorts of senseless c-casts, but modifiying a const object invokes undefined behavior.

By the way in the above example even for std::cout << a << ":" << a; the compiler would be allowed to emit code that prints 1:0 (or 42:3.1415927). When your code has undefinded behavior anything can happen.

PS: the function and the different outcomes is relevant if you want to study internals of your compiler and what it does to code that is not valid c++ code. For that you best look at the output of the compiler and how it differs in the two cases (https://godbolt.org/).

It is undefined behavior to cast a const variable and change it's value. If you try, anything can happen.

Anyway, what seems to happen, is that the compiler sees const int a = 0;, and, depending on optimization, puts it on the stack, but replaces all usages with 0 (since a will not change!). For *ra = 1;, the value stored in memory actually changes (the stack is read-write), and outputs that value.

For const int a = test();, dependent on optimization, the program actually calls the function test() and puts the value on the stack, where it is modified by *ra = 1, which also changes a.

Related