Why does const_cast remove constness for a pointer but not for a pointer to a const?

后端 未结 3 923
小鲜肉
小鲜肉 2021-02-05 12:31

I understand that const_cast works with pointers and references.

I\'m assuming that the input to const_cast should be a pointe

相关标签:
3条回答
  • 2021-02-05 13:10

    There are two kinds of constness.

    Constness of an object is an inherent property of an object. It cannot be changed.

    Think of a page in a printed book. It can be viewed as a string of characters, and it cannot be changed. It says what it says and that's it. So it's a const string.

    Now think of a blackboard. It may have something written on it. You can wipe that and write something else. So the blackboard is a non-const string.

    The other kind of constness is pointer and reference constness. This constness is not an inherent property of the pointed-to object, but a permission. It says you are not allowed to modify the object through this pointer. It says nothing about whether the object itself can be modified.

    So if you have a const pointer, you don't necessarily know what it really points to. Maybe it's a book page. Maybe it's a blackboard. The pointer doesn't tell.

    Now if you do know somehow that it is indeed a blackboard, you can be nasty and demand permission to go ahead and change what's written on it. That's what const_cast does. It gives you permission to do something.

    What happens if you demand permission to modify a string, and it turns out to be a printed page? You get your permission, you go ahead and wipe it... and... What exactly happens is undefined. Perhaps nothing at all. Perhaps the print is smeared and you can neither recognise the original string nor write anything on top. Perhaps your world explodes to little pieces. You can try and see, but there's no guarantee the same thing will happen tomorrow.

    0 讨论(0)
  • 2021-02-05 13:18

    (2) and (3) has the same principle, so I'll talk about (2) only.

    The line

    const_cast<int&>(ri) = 321;
    

    has undefined behavior.

    You cannot modify a const object according to the standard, not even with const_cast. If you remove const from a pointer/reference, and modify the pointed/referenced object, the pointed/referenced object must not been declared as const in the first place.

    const_cast should be used only, when you have a const pointer to something for some reason, and you know that something is not declared as const.

    0 讨论(0)
  • 2021-02-05 13:21

    Modifying the constant via the const_cast is undefined behaviour.

    The compiler sees that you are trying to print a constant variable, knows it can never change so compiles:

    cout << "i: " << i << endl;
    

    to:

    cout << "i: " << 123 << endl;
    

    see: https://godbolt.org/z/bYb0mx. With optimisations enabled it optimises your code to just printing 123: https://godbolt.org/z/4Ttlmj.

    Ultimately compilers make assumptions in order to create faster/smaller code, if you enter the realms of undefined behaviour some of those assumptions may be incorrect and produce surprising results.

    0 讨论(0)
提交回复
热议问题