通过非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;
试图修改该对象,因此结果是未定义的行为 。