This question already has answers here:
Two different values at the same memory address
(7 个回答)
3年前关闭。
输出看起来像:
并认为“啊,这永远不会改变,所以我们不需要一个“真正的”变量,可以简单地用
现在在下一行“欺骗”编译器:
并更改一个,尽管您已 promise 不这样做。
结果是困惑。
就像很多人已经提到的一样,Christian Hackl 在他出色的深入回答中进行了彻底的分析,这是未定义的行为。通常允许编译器对显式声明为
你的问题是一个很好的例子(我不知道怎么会有人投票反对它!)为什么
此外,您的同事将依赖
试试看:也许您的程序在调试构建(未优化)和发布构建(优化)中的行为甚至会有所不同,而这些错误通常很难修复。
(7 个回答)
3年前关闭。
#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;
并认为“啊,这永远不会改变,所以我们不需要一个“真正的”变量,可以简单地用
a
替换代码中所有出现的 10
”。这种行为称为 constant folding 。现在在下一行“欺骗”编译器:
auto *b = const_cast<int *>(&a);
*b = 20;
并更改一个,尽管您已 promise 不这样做。
结果是困惑。
就像很多人已经提到的一样,Christian Hackl 在他出色的深入回答中进行了彻底的分析,这是未定义的行为。通常允许编译器对显式声明为
const
的常量应用常量折叠。你的问题是一个很好的例子(我不知道怎么会有人投票反对它!)为什么
const_cast
非常危险(与原始指针结合时甚至更危险),应该只在绝对必要时使用,并且至少应该是彻底评论了为什么在不可避免的情况下使用它。在这种情况下,注释很重要,因为您“欺骗”的不仅仅是编译器:此外,您的同事将依赖
const
信息并依赖它不会更改的信息。但是,如果它确实发生了变化,而您没有通知他们,也没有发表评论,并且不完全知道您在做什么,那么您将在工作中度过糟糕的一天:)试试看:也许您的程序在调试构建(未优化)和发布构建(优化)中的行为甚至会有所不同,而这些错误通常很难修复。
关于c++ - C++ 如何保持 const 值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47236659/
10-11 06:32