const_cast 的奇怪行为

Weird Behaviour with const_cast(const_cast 的奇怪行为)
本文介绍了const_cast 的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我知道使用 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....

这篇关于const_cast 的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Could I ever want to access the address zero?(我可以想访问地址零吗?)
C++ Access derived class member from base class pointer(C++ 从基类指针访问派生类成员)
Are pointer variables just integers with some operators or are they quot;symbolicquot;?(指针变量只是带有某些运算符的整数还是“符号?)
Modifying a char *const string(修改 char *const 字符串)
Modifying a const int in C++(修改 C++ 中的 const int)
Check if a pointer points to allocated memory on the heap(检查一个指针是否指向堆上分配的内存)