Using const_cast to add const-ness - bad idea?

只愿长相守 提交于 2019-12-06 02:05:06

You should not use const_cast to add const, because:

  1. it's unnecessary. T* converts implicitly to const T*. Your question states that char sourcebuffer[] = {0x00}; copyfunction(sourcebuffer); is an error, but that's not true.

  2. it's potentially (albeit unlikely) harmful. It can remove volatile from the pointer type, which is not the intention here and would result in undefined behavior if sourcebuffer were declared as volatile sourcebuffer[].

You should not use const_cast to add const because

  1. In the cases where the operation is safe, it is almost always not required. int* turns into a const int* implicitly.

  2. It can do something you don't want it to do. It can strip volatile, or make you miss the fact that const was added somewhere else in your variables and your const_cast now silently strips them.

  3. In the cases where it is required to add const, its use is dangerous in hard to reason about ways.

There are cases where you need to call const_cast in order to add const that will not happen implicitly.

void assign_ptr( int const*& lhs, int const* rhs ) { lhs = rhs; }
int const foo = 7;
int* bar = nullptr;
assign_ptr( const_cast<int const*&>(bar), &foo );
*bar = 2; // undefined behavior!
std::cout << foo << "@" << &foo << "\n"; // will print probably 7@something
std::cout << *bar << "@" << bar << "\n"; // will print probably 2@same address as above!

the above call to assign_ptr only adds const, but it will not happen implicitly.

A side effect of it is that modification of *bar is undefined behavior, as it modifies a variable declared const (it makes bar, a int*, point at foo a const int).

So while const_cast is required to make the assign_ptr call compile, it is because it was unsafe. The const_cast doesn't make it safer, it just hides the error.

This is a specific case of the rectangle-square problem. Squares are not Rectangles, because if you change the width of a Square its height also changes, and this does not happen when you modify a Rectangle. Similarly, int** are not int const**. (Note that immutable Squares are a kind of immutable Rectangle; it is the mutation that causes the issue. In the case of pointers, a int*const* is a int const*const*: the mutability of the "higher level" pointers causes the problem.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!