我有这段代码:
const int x = 7;
const int &y = x;
int *z = (int*)&y;
*z = 8;
cout << x<< endl;
cout << y<< endl;
cout << *z<< endl;
产生以下输出:
7
8
8
我知道不应该像上面那样删除const。但是,为什么x打印7?我只创建了一个var,所以如果输出显示7和8,那么应该创建2个vars。怎么会有两个不同的数字印刷。
答案 0 :(得分:8)
我知道不应该像上面那样删除const。
右。这样做是未定义的行为,这意味着任何都可能发生。 (更准确地说,创建z
不是未定义的行为;通过它修改x
是。)
但是,为什么x打印7?我只创建了一个var,所以如果输出显示7和8,则应该创建2个vars。怎么会有两个不同的数字印刷。
关于未定义行为的推理很奇怪 - 但是理解调试目的是什么有用。在这种情况下,几乎可以肯定的是,编译器已经优化了:
cout << x<< endl;
到
cout << 7 << endl;
因为你无法合法地修改x的值。然后,您可以非法修改x的值,并设法打印出新值。
不要试图依赖这种行为;正如我上面所说,它仅用于调试目的。如果编译器更改它可能会在优化时变得更好并且只为所有值打印7(因为*z = 8
是未定义的行为),或者它可能将x
放在只读内存中(并导致访问冲突) ,或者它可能最终为所有值打印8,或者可能发生任何其他事情。
答案 1 :(得分:3)
但是,为什么x打印7?
修改const对象具有未定义的行为。
答案 2 :(得分:2)
抛弃const并使用指针修改const对象具有未定义的行为。你看到了结果。
该标准甚至与您发布的示例几乎相同。
除了声明可变的任何类成员都可以修改,任何 尝试在其生命周期内修改const对象 未定义的行为。 [实施例:
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
另一个例子,
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
- 结束示例]