考虑一下:
#include <iostream>
using namespace std;
int main(void)
{
const int a1 = 40;
const int* b1 = &a1;
char* c1 = (char *)(b1);
*c1 = 'A';
int *t = (int*)c1;
cout << a1 << " " << *t << endl;
cout << &a1 << " " << t << endl;
return 0;
}
这个输出是:
40 65
0xbfacbe8c 0xbfacbe8c
除非编译器进行优化,否则这对我来说几乎是不可能的。怎么样 ?
答案 0 :(得分:14)
这是undefined behavior,你正在修改一个const变量,所以你不能期望结果。我们可以通过转到草案C ++标准部分7.1.6.1
cv-qualifiers 段 4 来看到这一点:
[...]任何在生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。
甚至提供了一个例子:
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
在1.3.24
部分的未定义行为的标准定义中,给出了以下可能的行为:
[...]允许的未定义行为包括完全忽略不可预测的结果,在翻译或程序执行期间以环境特征的文件化方式行事(有或没有发布) 诊断消息),终止翻译或执行(发布诊断消息)。 [...]
答案 1 :(得分:4)
您的代码具有未定义的行为,因为您正在修改常量对象。 任何都可能发生,没有什么是不可能的。
答案 2 :(得分:2)
当你对变量const
进行限定时,编译器可以假设一些事情并生成代码,这可以正常工作,只要你尊重协议而不是破坏协议。当你破坏它时,你会得到未定义的行为。
请注意,删除const
后,它会按预期工作; here's a live example
答案 3 :(得分:0)
正如其他人所解释的那样,修改const
值会导致未定义的行为,不需要再说了 - 任何结果都是可能的,包括完全废话或崩溃。
如果您对此特定结果的出现感到好奇,那几乎可以肯定是由于优化。由于您将a
定义为const
,因此编译器可以随时替换您分配给它的值40
;毕竟,它的价值无法改变,对吧?例如,当您使用a
来定义数组的大小时,这非常有用。即使在gcc中,它具有可变大小数组的扩展,编译器也可以更简单地分配一个恒定大小的数组。一旦优化存在,它可能会一致地应用。