Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 同一地址的变量如何产生两个不同的值?_C++_Casting_Constants_Undefined Behavior - Fatal编程技术网

C++ 同一地址的变量如何产生两个不同的值?

C++ 同一地址的变量如何产生两个不同的值?,c++,casting,constants,undefined-behavior,C++,Casting,Constants,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 << en

考虑这一点:

#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;
}

这对我来说几乎是不可能的,除非编译器正在进行优化。怎么做

您的代码具有未定义的行为,因为您正在修改常量对象。任何事情都有可能发生,没有什么是不可能的。

这就是说,您正在修改一个常量变量,以便对结果没有任何期望。我们可以看到C++的标准部分7.1.6-1的CV限定符第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节未定义行为的标准定义中,给出了以下可能的行为:

[…]允许的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行过程中以记录的方式(无论是否发布 诊断消息,通过发出诊断消息来终止转换或执行。[……]


当您限定它们为常量变量时,编译器可以假设一些事情并生成代码,只要您尊重这一约定,而不是破坏它,这就可以很好地工作。当你打破它,你会得到未定义的行为


请注意,删除const后,它将按预期工作

正如其他人所解释的,修改常量值会导致未定义的行为,无需多说-任何结果都是可能的,包括完全的胡说八道或崩溃


如果您对这个特定结果是如何产生的感到好奇,几乎可以肯定这是由于优化。由于您将a定义为常量,编译器可以随时替换您分配给它的值40;毕竟,它的价值是不会改变的,对吧?例如,当您使用定义数组大小时,这非常有用。即使在gcc中(它有一个用于可变大小数组的扩展),编译器也更容易分配一个恒定大小的数组。一旦优化存在,它可能会被一致地应用。

为什么修改常量变量会导致未定义的行为?@Ben,因为规范这么说。@Ben,正如巴特所说,因为标准这么说。该标准这样说的原因是1允许编译器将变量放入只读内存,例如,您试图修改它可能会导致程序崩溃;2允许编译器将常量值作为常量表达式传播:如果您稍后编写char arr[a1];,你希望数组有多大?@JamesKanze好的,谢谢。@ben一个常量应该是常量,如果它改变了,就不应该是常量。因此,试图这样做,在语义上是胡说八道。如果有人在运行过程中改变PI值,会发生什么?胡说八道,没有定义的行为。C++让你做非常危险的事情,这是C++的一个力量,但是有时危险会导致胡说八道。如果你的问题已经被回答了,请不要发表评论,感谢回答者。您也可以选择已接受的答案以及您认为有用的任何其他答案。谢谢。我会记住的。
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