修改const值的"undefined-ness"机制

Dov*_*Dov 1 c++ pointers const undefined-behavior constantfolding

我已经读过,它在某些C标准(可能是99?)中未定义,当修改const时会发生什么.但是一位学生向我提供了一些我修改过的代码.

我看不出常量变量的地址有什么特别之处a.我验证了它&a并且b是相同的,因此编译器不会巧妙地指向其他位置.然而,当我分配时*b,const值不会改变.

我没有运行优化.当我使用-g标志进行编译以进行调试并进入代码时,我得到了我期望的结果(变量的内存位置发生了a变化).然而,下面提供的代码并未反映更新后的价值a.

即使在调试模式下,这个temp现在也被放在寄存器中,没有优化吗?

#include <iostream>

using namespace std;

int main(){
    const int a = 15;
    cout << a << '\n';
    int * b= (int*)&a;
    cout << &a << "\n";
    cout << b << "\n";
    *b = 20;
    cout << *b << '\n';
    cout << a << '\n';

    int x = a;
    cout << x << '\n';
    x = *b;
    cout << x << '\n';
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*our 5

这也是C++中未定义的行为,我们可以通过转到草案C++标准部分7.1.6.1 cv-qualifiers4段来看到这一点:

[...]任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为.

未定义的行为意味着结果是不可预测的,这实际上意味着即使是那些乍一看也无视直觉的结果也是可能的.

快速实验godbolt使用-O0,所以没有优化回事显示了编译器只是用字面值15a,而不是从内存中检索并打印了这一点的:

movl    $15, %esi   #,
Run Code Online (Sandbox Code Playgroud)

所以编译器正在执行常量折叠,因为它假设因为它a是常量,所以它只能15在它看到的任何地方使用它a.这是完全合理的,因为你告诉它a是不变的.