Modifying a const object

suggest change

Any attempt to modify a const object results in undefined behavior. This applies to const variables, members of const objects, and class members declared const. (However, a mutable member of a const object is not const.)

Such an attempt can be made through const_cast:

const int x = 123;
const_cast<int&>(x) = 456;
std::cout << x << '\n';

A compiler will usually inline the value of a const int object, so it’s possible that this code compiles and prints 123. Compilers can also place const objects’ values in read-only memory, so a segmentation fault may occur. In any case, the behavior is undefined and the program might do anything.

The following program conceals a far more subtle error:

#include <iostream>

class Foo* instance;

class Foo {
  public:
    int get_x() const { return m_x; }
    void set_x(int x) { m_x = x; }
  private:
    Foo(int x, Foo*& this_ref): m_x(x) {
        this_ref = this;
    }
    int m_x;
    friend const Foo& getFoo();
};

const Foo& getFoo() {
    static const Foo foo(123, instance);
    return foo;
}

void do_evil(int x) {
    instance->set_x(x);
}

int main() {
    const Foo& foo = getFoo();
    do_evil(456);
    std::cout << foo.get_x() << '\n';
}

In this code, getFoo creates a singleton of type const Foo and its member m_x is initialized to 123. Then do_evil is called and the value of foo.m_x is apparently changed to 456. What went wrong?

Despite its name, do_evil does nothing particularly evil; all it does is call a setter through a Foo*. But that pointer points to a const Foo object even though const_cast was not used. This pointer was obtained through Foo’s constructor. A const object does not become const until its initialization is complete, so this has type Foo*, not const Foo*, within the constructor.

Therefore, undefined behavior occurs even though there are no obviously dangerous constructs in this program.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Undefined behavior:
* Modifying a const object

Table Of Contents
8 Arrays
11 Loops
39 Streams
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
71 Undefined behavior
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype