我知道使用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
答案 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
没有改变,因此你可能会遇到问题....