C++ C++;常量指针-无法解释的行为

C++ C++;常量指针-无法解释的行为,c++,pointers,reference,C++,Pointers,Reference,我有一段代码: const int x = 7; const int &y = x; int *z = (int*)&y; *z = 8; cout << x<< endl; cout << y<< endl; cout << *z<< endl; 我知道不应该像我上面所做的那样移除常量。然而,为什么x打印出7?我只创建了一个变量,所以如果输出显示7和8,那么应该创建两个变量。为什么会有两个不同的数字打

我有一段代码:

const int x = 7;
const int &y = x;

int *z = (int*)&y;
*z = 8;

cout << x<< endl;
cout << y<< endl;
cout << *z<< endl;
我知道不应该像我上面所做的那样移除常量。然而,为什么x打印出7?我只创建了一个变量,所以如果输出显示7和8,那么应该创建两个变量。为什么会有两个不同的数字打印出来

然而,为什么x打印出7


修改常量对象具有未定义的行为。

丢弃常量并使用指针修改常量对象具有未定义的行为。你看到了结果

该标准甚至与您发布的示例几乎相同

除了任何声明为可变的类成员都可以修改之外,任何 尝试在常量对象的生存期内修改它会导致 未定义的行为。[ 例如:

const int ci = 3;                       // cv-qualified (initialized as required)
ci = 4;                                 // ill-formed: attempt to modify const

int i = 2;                              // not cv-qualified
const int* cip;                         // pointer to const int
cip = &i;                               // OK: cv-qualified access path to unqualified
*cip = 4;                               // ill-formed: attempt to modify through ptr to const

int* ip;
ip = const_cast<int*>(cip);             // cast needed to convert const int* to int*
*ip = 4;                                // defined: *ip points to i, a non-const object

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
const int ci=3;//cv合格(根据需要初始化)
ci=4;//格式错误:试图修改常量
int i=2;//不符合cv条件
常量int*cip;//指向常量int的指针
cip=&i;//确定:cv限定访问路径到非限定访问路径
*cip=4;//格式错误:试图通过ptr修改为常量
int*ip;
ip=const_cast(cip);//将const int*转换为int所需的cast*
*ip=4;//定义:*ip指向i,一个非常量对象
const int*ciq=new const int(3);//根据需要初始化
int*iq=const_cast(ciq);//需要强制铸造
*iq=4;//未定义:修改常量对象
再比如,

struct X {
  mutable int i;
  int j;
};
struct Y {
  X x;
  Y();
};

const Y y;
y.x.i++;                                // well-formed: mutable member can be modified
y.x.j++;                                // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y);              // cast away const-ness of y
p->x.i = 99;                            // well-formed: mutable member can be modified
p->x.j = 99;                            // undefined: modifies a const member
struct X{
可变intⅠ;
int j;
};
结构{
X;
Y();
};
常数;
y、 x.i++;//格式正确:可以修改可变成员
y、 x.j++;//格式错误:修改了常量限定成员
Y*p=const_cast(&Y);//丢弃Y的常量
p->x.i=99;//格式正确:可以修改可变成员
p->x.j=99;//未定义:修改常量成员
 — 结束示例 ]

我知道不应该像我上面所做的那样移除常量

对。这样做是未定义的行为,这意味着任何事情都可能发生。(更准确地说,创建
z
不是未定义的行为;通过它修改
x

然而,为什么x打印出7?我只创建了一个变量,所以如果输出显示7和8,那么应该创建两个变量。为什么会打印出两个不同的数字

关于未定义行为的推理很奇怪,但为了调试目的,理解正在发生的事情可能很有用。在这种情况下,几乎可以肯定的是,编译器已经优化了:

cout << x<< endl;

<代码> CUT,但如果8被打印,这是否意味着C++创建了一个内部变量,因此你将有4个额外的字节分配?@ GooCudies——不,这意味着行为是不明确的。C++不承诺任何特定的事情发生,不同的编译器可以做任何他们喜欢的事情。@ GooCudies不,你不能做出这样的结论。要了解编译器选择了做什么,您可以检查程序集。谢谢Martin,您的答案最好地解释了我在寻找什么。我认为可能会发生类似的情况。向上投票。我在调试模式下在OS X上的clion 2017.1中对其进行了测试,变量观察器说修改后的
X
为8。所以我猜您的原因是什么输出中的got 7是编译器将变量标识符优化为数字文字,因为它假定
x
const
。不应依赖某些特定编译器提供的此优化功能。可能会出现编译器错误或运行时错误或未更改的“7”在另一个编译器上——这就是“未定义行为”的含义。@NandiinBao——奇怪的巧合是,你的评论几乎完全符合我在回答中所附的内容:-)。伟大的人都是这样想的!啊,好吧。我使用了GCC。可能将
volatile
添加到
x
中会改变这种行为,但这仍然是未定义的行为,而你呢我们应该避免它。
cout << x<< endl;
cout << 7 << endl;