我尝试过以下代码:
#include <iostream>
using namespace std;
struct MyClass {
const int x;
};
int main() {
MyClass c = {3};
const int *p = &c.x;
cout << "x = " << c.x << endl;
cout << "&x = " << &c.x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&c.x) << endl;
cout << endl;
*(int*)&c.x = 4;
cout << "x = " << c.x << endl;
cout << "&x = " << &c.x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&c.x) << endl;
cout << (p == &c.x) << endl;
cout << (*p == *(&c.x)) << endl;
return 0;
}
然后我得到以下答案:
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 3
*(&x) = 3
x = 4
&x = 0x61fe98
p = 0x61fe98
*p = 4
*(&x) = 4
1
1
似乎我已成功更改常量整数x的值。但是当我直接在main()中而不是在类中声明x时,我会得到完全不同的答案。
#include <iostream>
using namespace std;
int main() {
const int x = 3;
const int *p = &x;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&x) << endl;
cout << endl;
*(int*)&x = 4;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&x) << endl;
cout << endl;
cout << (p == &x) << endl;
cout << (*p == *(&x)) << endl;
return 0;
}
结果是
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 3
*(&x) = 3
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 4
*(&x) = 3
1
0
(p ==&amp; x)是真的很奇怪但是(* p == *(&amp; x))是假的!!!我不知道第二个代码中发生了什么。
答案 0 :(得分:2)
你正在做的是undefined behaviour,所以任何事情都可能发生。 C ++标准说:
除了可以修改声明为
mutable
(10.1.1)的任何类成员之外,任何在其生命周期内修改const
对象的尝试(6.8)都会导致未定义的行为。
和
[注意:根据对象的类型,通过指针,左值或指向数据成员的指针的写入操作可以转移一个const限定符
const_cast
产生未定义 行为(10.1.7.1)。 - 结束说明]
所以你可以抛弃&#34; const&#34;获取int*
但是尝试通过该指针实际修改变量是未定义的。
你可以抛弃const
的原因是它实际上可能没有指向常数:
int i = 0;
const int* p = &i;
*(int*)p = 1; // OK, because p points to a non-constant
const int j = 0;
const int* q = &j;
*(int*)q = 1; // NOT OK, because q points to a constant
在你的第二个例子中,编译器在优化时做出假设,基于它知道常量值不会改变的事实,所以它不会打扰测试它的值。这个假设是正确的,因为正确的程序永远不能改变常量的值。你的程序不正确,但这意味着编译器不需要给出合理的结果。