1

我已经读过,在某些 C 标准(可能是 99?)中未定义它在修改 const 时会发生什么。但是一个学生给了我一些代码,我对其进行了修改。

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

我没有运行优化。当我使用-g标志进行编译以调试并单步执行代码时,我得到了我期望的结果(变量的内存位置发生了a变化)。然而,下面显示的代码并未反映a.

即使在调试模式下,临时工现在也被放置在寄存器中,没有优化?

#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;
}
4

1 回答 1

5

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

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

未定义的行为意味着结果是不可预测的,这实际上意味着任何结果都是可能的,即使是乍一看违反直觉的结果。

一个使用godbolt的快速实验,-O0因此没有进行优化,表明编译器只是使用文字值15a而不是从内存中检索它并打印出来:

movl    $15, %esi   #,

所以编译器正在执行常量折叠,因为它假定既然a是常量,它就可以15在它看到的任何地方使用该值a。这是完全合理的,因为您告诉它a是恒定的。

于 2014-10-10T03:39:25.557 回答