修改const常量后打印它的值,是修改前的值?

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    const int a = 10;
    int* p = (int*)&a;
    *p = 100;

    cout << a << endl; // 10
    cout << *p << endl; // 100

    // 下面两行打印地址一样
    cout << &a << endl;
    cout << p << endl;

    return 0;
}

请问这是怎么回事?我已经修改了 a 的值,为什么打印 a 还是 10

阅读 2.7k
3 个回答

这属于未定义行为,不建议在正式代码中使用。而 a 之所以还是 10,可能是编译器优化的结果(部分编译器编译结果不是 10)。可以把汇编代码导出看看。

这里涉及一个编译器优化概念,叫做常量传播。你把a变量设置为const,就是告诉编译器这个变量不会改变,那么在编译时期,所有用到a的地方,能替换成10的都换了,但是还会给a分配一个空间,所以你能看到a的地址。
你可以在const int a = 10;之前加一个关键字 volatile,变成volatile const int a = 10;这样结果就都是100了,这个关键字告诉编译器不要对这个变量做某种假设来进行优化。每次需要的时候都从内存里面取出来,就不会有传播优化。
另外强调一下,这样对const变量进行修改是个undefined behavior操作,不同的编译器可能会有不同结果,实际不能这么用。

因为编译器把a的值放进了符号表。当程序中有用到符号a时,就从符号表中把值10取出来用。
当使用&取地址符或者extern关键字作用于a时,这时候编译器会在内存里分配一段空间。实际上p修改的是这段内存里的值,并没有修改a的值,遇到a,编译器仍然会直接替换为10。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题