#include <iostream>
using namespace std;
int main() {
const int a = 10;
auto *b = const_cast<int *>(&a);
*b = 20;
cout << a << " " << *b;
cout << endl << &a << " " << b;
}
输出如下:
10 20
0x7ffeeb1d396c 0x7ffeeb1d396c
a
和*b
在同一个地址,为什么它们的值不同?
这很可能是由优化引起的。
正如 molbdnilo 在他的评论中所说:“编译器盲目地信任你。如果你对他们撒谎,就会发生奇怪的事情。”
所以当启用优化时,编译器会找到声明
const int a = 10;
并认为“啊,这永远不会改变,所以我们不需要一个“真正的”变量并且可以用 10
替换代码中所有出现的 a
>”。此行为称为 constant folding .
现在在下一行中“欺骗”编译器:
auto *b = const_cast<int *>(&a);
*b = 20;
并改变a,虽然你已经 promise 不会这样做。
结果是困惑。
就像很多人已经提到的,Christian Hackl 在他出色的深入回答中已经彻底分析过,这是未定义的行为。通常允许编译器对显式声明为 const
的常量应用常量折叠。
你的问题是一个很好的例子(我不知道怎么会有人拒绝它!)为什么 const_cast
非常危险(与原始指针结合使用时更危险),应该只是绝对必要时使用,如果不可避免,至少应彻底说明为什么使用它。在这种情况下,注释很重要,因为你“欺骗”的不仅仅是编译器:
您的同事也将依赖于信息 const
并且依赖于它不会改变的信息。如果它确实发生了变化,而你没有通知他们,没有发表评论,也没有完全知道你在做什么,那么你今天的工作会很糟糕:)
尝试一下:也许您的程序甚至在调试构建(未优化)和发布构建(优化)中表现不同,而且这些错误通常很难修复。