Search code examples
c++pointersconstantsundefined-behaviorconstantfolding

mechanism for "undefined-ness" of modifying the value of a const


I have read, it is undefined in some C standards (perhaps 99?) what happens when a const is modified. But a student presented me with some code, which I modified.

I cannot see anything special about the address of the constant variable a. I verified that &a and b are the same, so the compiler is not subtly pointing to some other location. Yet when I assign *b, the const value does not change.

I am not running with optimization. When I compile with the -g flag to debug and step into the code, I get the results I expect (the memory location of the variable a changes). Yet the code presented below does not reflect the updated value of a.

Is this that temps are now being placed in registers even in debug mode, with no optimization?

#include <iostream>

using namespace std;

int main(){
    const int a = 15;
    cout << a << '\n';
    int * b= (int*)&a;
    cout << &a << "\n";
    cout << b << "\n";
    *b = 20;
    cout << *b << '\n';
    cout << a << '\n';

    int x = a;
    cout << x << '\n';
    x = *b;
    cout << x << '\n';
    return 1;
}

Solution

  • This is also undefined behavior in C++, we can see this by going to the draft C++ standard section 7.1.6.1 The cv-qualifiers paragraph 4 which says:

    [...]any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

    Undefined behavior means the results are unpredictable which effectively means any result is possible even ones that at first glance defy intuition.

    A quick experiment with godbolt using -O0 so there is no optimization going on shows the compiler is just using the literal value 15 for a instead of retrieving it from memory and printing that out:

    movl    $15, %esi   #,
    

    So the compiler is performing constant folding since it assumes that since a is constant it can just use the value 15 anywhere it sees a. Which is completely reasonable since you told it a was constant.