通过非const指针修改一个const

我有点困惑以下代码发生了什么事情:

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指针和&e的值,则它们具有相同的值/地址。

e怎么仍然包含2,即使它变成了5? 他们是否存储在一个单独的位置? 还是暂时的? 但是,w所指的价值究竟是e的地址呢?

正如我在评论中所说的那样,一旦你修改了const值,你就处于未定义的行为状态,所以谈论正在发生的事情并没有什么意义。 但是到底是什么

 cout << *w << endl; // (3) outputs 5 cout << e << endl; // (4) outputs 2 

猜测, *w正在运行时被评估,但是e被当作​​编译时间常量

我怀疑你正在编译器。 它不指望你玩e的脏伎俩,所以当它看到的线:

 cout << e << endl; 

它只是插入值2,而不是查找实际值。 您可以通过查看程序的反汇编来validation(或反驳)。

我猜测编译器已经优化了输出值。 它认为e是常量(所以它不能在理论上改变)并且改变cout << e << endl;cout << 2 << endl; 。 然而, e仍然必须存在,因为它被w ,所以w正确地接受它的地址并修改它的值,但是在cout没有看到。

这个故事的道德 – 只有当你真的想成为const时候才会声明const 。 抛弃const不是一个好主意。

我能想到的唯一的事情是编译器有一些如何优化代码的方式,即任何对e的引用都被replace为值2,即使它为e

所以实际上(影响?)注释(4)处的行是“优化”的

 cout << "2" << endln; 

我猜编译器使用const来优化variables,并在代码中插入一个固定的值。

这包括在C ++ 14标准的[dcl.type.cv] / 4中(以前的标准也有类似的文字):

除了任何声明mutable类成员可以被修改外,任何尝试在其生命周期中修改const对象都会导致未定义的行为。

e是一个const对象, *w = 5; 试图修改该对象,因此结果是未定义的行为 。