同一地址的变量如何产生2个不同的值?

时间:2014-03-26 09:34:22

标签: c++ casting const undefined-behavior

考虑一下:

#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

除非编译器进行优化,否则这对我来说几乎是不可能的。怎么样 ?

4 个答案:

答案 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中,它具有可变大小数组的扩展,编译器也可以更简单地分配一个恒定大小的数组。一旦优化存在,它可能会一致地应用。