我对以下代码中发生的事情感到有点困惑:
const int e = 2;
int* w = ( int* ) &e; // (1) cast to remove const-ness
*w = 5; // (2)
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
cout << "w = " << w << endl; // (5) w points to the address of e
cout << "&e = " << &e << endl;
在(1)中,w指向e的地址。在(2)中,该值变为5.但是,当显示* w和e的值时,它们的值不同。但是如果你打印w指针和&amp; e的值,它们就有相同的值/地址。
为什么e仍然包含2,即使它被改为5?他们存放在一个单独的位置?还是暂时的?但是为什么w所指出的价值仍然是e?
的地址答案 0 :(得分:17)
正如我在评论中所说,一旦修改了const值,你就处于未定义的行为状态,所以谈论正在发生的事情并没有多大意义。但到底是怎么回事......
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
猜测,*w
正在运行时进行评估,但e
被视为编译时常量
答案 1 :(得分:8)
我怀疑你正在绊倒编译器。它并不指望你用e玩肮脏的技巧,所以当它看到这条线时:
cout << e << endl;
它只是插入值2而不是查找实际值。您可以通过查看程序的反汇编来验证(或反驳)。
答案 2 :(得分:4)
我猜测编译器已优化了值输出。它看到e
是const(因此,理论上它不能改变)并且将cout << e << endl;
更改为cout << 2 << endl;
。但是,e
仍然必须存在,因为w
使用了w
,因此cout
正确获取其地址并修改其值,但您在const
中看不到
故事的道德 - 只在您真正想要const
时声明事物const
。抛弃{{1}}并不是一个好主意。
答案 3 :(得分:3)
我唯一能想到的是编译器有一些如何优化代码的方式,即使为e指定内存,对e的任何引用都被替换为值2
如此有效(影响?)注释(4)中的行被“优化”为
cout << "2" << endln;
答案 4 :(得分:2)
我猜编译器使用constness来优化变量并在代码中插入一个固定值。
答案 5 :(得分:1)
C ++ 14标准的[dcl.type.cv] / 4节(早期标准也有类似的文字)涵盖了这一点:
除了可以修改声明为
mutable
的任何类成员之外,任何在其生命周期内修改const
对象的尝试都会导致未定义的行为。
e
是一个const对象,*w = 5;
尝试修改该对象,因此结果为undefined behavior。