我已经读过,在某些C标准(可能是99 ?)中未定义,修改const时会发生什么。但是一位学生向我提供了一些我修改过的代码。
我看不出常量变量a
的地址有什么特别之处。我确认&a
和b
是相同的,因此编译器不会巧妙地指向其他位置。
然而,当我分配*b
时, const 值不会改变。
我没有运行优化。当我使用-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;
}
答案 0 :(得分:5)
这也是C ++中的undefined behavior,我们可以通过转到草案C ++标准部分7.1.6.1
cv-qualifiers 段 4 其中说:
[...]任何在生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。
未定义的行为意味着结果是不可预测的,这实际上意味着即使是那些乍一看也无视直觉的结果也是可能的。
godbolt使用-O0
的快速实验,因此没有进行优化表明编译器只使用15
的文字值a
而不是从movl $15, %esi #,
检索它记忆和打印:
a
因此,编译器正在执行constant folding,因为它假设15
是常量,因此只需在a
所见的任何位置使用值a
。这是完全合理的,因为你告诉它{{1}}是不变的。