const_cast rules in c++
Asked Answered
B

1

8
struct foo
{
    const int A;
    int B;
    foo() : A(10), B(20) {}
};

void main()
{
    foo f1;
    const_cast<int&>(f1.A) = 4; //line 1
    const foo f2;
    const_cast<int&>(f2.B) = 4; //line 2
}

Do both line 1 and 2 exhibit undefined behaviour? Would the behavior be different if f1 and f2 were shared_ptr of types listed in code above?

Boutte answered 5/6, 2018 at 14:49 Comment(1)
It does not matter what data type is loosing constness, problem is compiler can assume that object does not change and produce relevant code.Undertrump
S
15

The behaviour both const_cast<int&>(f1.A) = 4 and const_cast<int&>(f2.B) = 4 are undefined.

If an object is originally defined as const, and you cast away that const-ness and attempt to modify the object, the behaviour is undefined.

Saccharase answered 5/6, 2018 at 14:51 Comment(5)
@YSC: Hum. Could've sworn f2 was non-const originally. Still, only a little edit needed. Thanks.Saccharase
Edits making non-const object now const (even sneaky edits made on Fridays) are welcome. I wish there was more of them at work.Offenseless
As an addendum, if an object is originally non-const, and then passed through a const pointer or const reference, and then const_cast back to non-const, I believe that is well-defined behavior. But, in my opinion, it is still a bad code smell to const_cast away const-ness even if the developer KNOWS it is a non-const object really really.Blackboard
@Eljay: Yes you are correct, both factually and stylistically. It's only if you attempt to modify the object do you get undefined results.Saccharase
@Blackboard there's the school of thought for de-duplicating getter's of the style class Foo { const Bar& do_get() const { /* single impl */ } public: Bar& get() { return const_cast<Bar&>(do_get()); } const Bar& get() const { return do_get(); } };Acid

© 2022 - 2024 — McMap. All rights reserved.