Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning a value to a const class member

Tags:

c++

Is there UB in the code below?

#include <iostream>

int* p_n;

class A
{
public:

    A(int val) : n(val)
    {
        // At this point the compiler does not know if the object is const or not.
        p_n = &n;
    }

    int n;
};

int main()
{
    // A::n is const, because A is const, right?
    const A a(1);

    // but we change a const value here
    *p_n = 2;

    std::cout << a.n << std::endl;

    return 0;
}

Is there a difference between assigning *p_n and doing this?

const_cast<A&>(a).n = 2;

EDIT

From here:

const and volatile semantics (7.1.6.1) are not applied on an object under construction. They come into effect when the constructor for the most derived object (1.8) ends.

While object a is under construction, it is not const and a.n is not const, but they become const when the constructor ends.

So, does p_n point to the const object or not?

like image 271
Dmitriano Avatar asked Sep 17 '25 23:09

Dmitriano


1 Answers

Yes. The code attempts to modify an int which is const. It does that by circumventing const-correctness, in the way you already discovered.

// A::n is const, because A is const, right?
const A a(1);

Yes. a is const, hence a.n cannot be modified.

// but we change a const value here
*p_n = 2;

Once you managed to bypass const and modify a.n, which cannot be modified, all bets are off. The code has undefined behavior.

is there a difference between assigning *p_n and doing this:

const_cast<A&>(a).n = 2;

No. const_cast does not change the fact that a is const.

Consider that you can have a pointer to const, or a const reference to an object that is not actually const, eg:

 int x = 42;
 const int& ref = x;

Here you could cast away constness from the reference to modify the integer. The integer is not const. Taking a const reference does not change that the object itself is not const. Similar in your example, no pointer hackery nor casts will change the constness of a.


Concerning your edit... It does not change the fact that a is const and that a.n once constructed is const. The quote you added merely explains the hole in const-correctness your code uses to invoke undefined behavior.

The reason const is only applied after construction is that otherwise a constructor that constructs a const object would be pretty useless. The constructor is needed to establish the class invariants, which typically requires to modify the object.

like image 93
463035818_is_not_a_number Avatar answered Sep 19 '25 17:09

463035818_is_not_a_number



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!