使用const_cast的奇怪行为

时间:2014-03-13 21:34:03

标签: c++ pointers casting

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

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

有没有人对此有解释?

代码

#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

2 个答案:

答案 0 :(得分:5)

该程序未定义bahaviour,因为您可能无法更改const对象。

来自C ++标准

  

4本国际上描述了某些其他操作   标准为未定义(例如,尝试修改的效果   一个const对象)。 [注:本国际标准规定不予批准   对包含undefined的程序行为的要求   行为。 - 后注]

答案 1 :(得分:2)

所以,除了&#34;它未定义的行为&#34; (它是),在M的评估中,编译器完全可以使用cout ... << M << ...是常量,因此不会发生变化的事实,因此可以使用具有的指令立即值10,而不是存储在M内存中的实际值。 (当然,标准不会说它是如何工作的,超过&#34;它未定义&#34;,并且编译器能够在不同情况下选择不同的解决方案等,所以它&#39;如果你修改代码,使用不同的编译器,不同版本的编译器或者风向不同的方向,你完全有可能得到不同的结果。

部分棘手的问题&#34;未定义的行为&#34;是它包含的东西是完全符合你的期望的#34;以及&#34;几乎你所期望的&#34;。如果发现这就是你正在做的事情,编译器也可以决定启动俄罗斯方块。

是的,这是你不应该使用const_cast的原因之一。至少不是原来const的东西 - 如果你有这样的话,那就没关系了:

int x;

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

  *q = 7;
}


...

 func(&x);

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