const_cast 的奇怪行为

2021-12-13 00:00:00 pointers casting c++

我知道使用 const_cast 通常是个坏主意,但我在玩它时遇到了一个奇怪的行为,其中:

I know that using const_cast is generally bad idea, but I was playing around with it and I came across a weird behaviour, where:

两个指针具有相同的地址值,但在取消引用时,给出不同的数据值.

Two pointers have the same address value, yet when de-referenced, give different data values.

有人对此有解释吗?

代码

#include <iostream>

int main()
{
    const int M = 10;

    int* MPtr = const_cast<int*>(&M);

    (*MPtr)++;

    std::cout << "MPtr = " << MPtr << "   (*MPtr) = " << (*MPtr) << std::endl;
    std::cout << "  &M = " << &M << "         M = " << M << std::endl;
}

输出

MPtr = 0x7fff9b4b6ce0   (*MPtr) = 11
  &M = 0x7fff9b4b6ce0         M = 10

推荐答案

所以,除了它是未定义的行为"(它是)之外,编译器完全可以使用 M 是一个常数,因此在 cout ... << 的评估中不会改变.M<<...,因此可以使用立即数为 10 的指令,而不是 M 内存中存储的实际值.(当然,标准不会说这是如何工作的,更多的是未定义",并且编译器能够在不同的情况下选择不同的解决方案等等,所以如果你修改,你完全有可能得到不同的结果代码,使用不同的编译器,不同版本的编译器或风向不同的方向吹).

So, aside from the "it's undefined behaviour" (which it is), the compiler is perfectly fine to use the fact that M is a constant, thus won't change, in the evaluation of cout ... << M << ..., so can use an instruction that has the immediate value 10, instead of the actual value stored in the memory of M. (Of course, the standard will not say how this works, more than "it's undefined", and compilers are able to choose different solutions in different circumstances, etc, etc, so it's entirely possible that you'll get different results if you modify the code, use a different compiler, different version of compiler or the wind is blowing in a different direction).

未定义行为"的部分棘手之处在于它包括完全符合您的预期"以及几乎符合您的预期"的内容.如果编译器发现您正在执行此操作,它也可以决定启动俄罗斯方块.

Part of the tricky bit with "undefined behaviour" is that it includes things that are "perfectly what you may expect" as well as "nearly what you'd expect". The compiler could also decide to start tetris if it discovers this is what you are doing.

是的,这也是您不应该使用 const_cast 的原因之一.至少不是那些最初是 const 的东西――如果你有这样的东西就可以了:

And yes, this is very much one of the reasons why you SHOULD NOT use const_cast. At the very least NOT on things that were originally const - it's OK if you have something along these lines:

int x;

void func(const int* p)
{
  ...
  int *q = const_cast<int *>(p);

  *q = 7;
}


...

 func(&x);

在这种情况下,x 实际上并不是 const,当我们将它传递给 func 时,它只是变成了 const.当然,编译器可能仍然假设 xfunc 中没有改变,因此你可能会遇到问题......

In this case, x is not actually const, it just becomes const when we pass it to func. Of course, the compiler may still assume that x is not changed in func, and thus you could have problems....

相关文章