c++ - C++ 如何保持 const 值?

标签 c++ compiler-optimization

<分区>

#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 并且依赖于它不会改变的信息。如果它确实发生了变化,而你没有通知他们,没有发表评论,也没有完全知道你在做什么,那么你今天的工作会很糟糕:)

尝试一下:也许您的程序甚至在调试构建(未优化)和发布构建(优化)中表现不同,而且这些错误通常很难修复。

关于c++ - C++ 如何保持 const 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47236659/

相关文章:

haskell - 'MutVar#'是什么意思?

haskell - GHC 部分评估和单独编译

c++ - 除非使用 cout,否则代码不会执行

c++ - gmock TypedEq 相同的字符串不同的地址

用于理解电话线上的音调信号的 C++ api

c++ - CBlobCache 用法 - ATL Server 库

c++ - C++中的饱和短(int16)

c# - 打开/关闭编译器优化标志的CPU密集型应用程序

c++ - 使用 C++ 编译 GNU C 项目

c++ - 完美转发,为什么析构函数被调用了两次?