这是我的测试代码:
#define print(A) cout << #A << " = " << A << endl;
int main()
{
const int e = 2;
int *p = (int *)&e;
*p = 4;
print(e);
print(*p);
print(&e);
print(p);
}
结果:
e = 2;
*p = 4;
&e = 0xbfc6b458;
p = 0xbfc6b458;
由于“p”根据相同的地址指向“e”,* p和“e”如何不同?这可能很危险,对吗?
答案 0 :(得分:8)
弃掉const
是合法的;使用这样获取的指针(或引用)来(尝试)修改const
对象是非法的。
您的代码会导致未定义的行为;它可以做任何事情而且没有任何意义。
答案 1 :(得分:3)
以任何方式修改常量变量会导致未定义行为 所以这是危险的 未定义的行为意味着任何行为都是可能的,您不能指望任何有效的行为。编译器可以自由地为您提供任何结果,标准允许这样做。一旦UB被调用,该程序就不再是一个有效的程序。所以最好避免任何导致UB的代码。
答案 2 :(得分:1)
它们可以是不同的,因为“e”是一个const,所以任何体面的编译器都会在编译时插入值而不是从内存中读取它。
由于您使用地址仍然有一个“真正的”变量,但实际上并没有在您的情况下使用。
你很幸运,你可以修改价值;因为它被声明为“const”,所以编译器可以将它放入只读内存中。
无论哪种方式,修改const值都会产生“未定义的行为”。幸运的是,你没有用愚蠢的游戏摧毁世界。
答案 3 :(得分:0)
你试图写一个常量变量(是的,这个名字是相当矛盾的,但我离题了)这是未定义的行为。
答案 4 :(得分:0)
你正在抛弃const。这给你错误的值,这是未定义的行为。 它应该是
int e = 2;
int* p = (int *)&e;
*p = 4;
或
const int e = 2;
const int* p = (const int *)&e;
*p = 4;
后者会在写入const时给出编译错误。
答案 5 :(得分:0)
定义变量:
const int e = 2;
指令const告诉c / c ++编译器检查e变量的L值,编译器会阻止你的代码为e赋值。
int* p = (int *)&e;
p是一个指针(也是int 4个字节),可以赋值任意值,p =(((int *)e)-2)+2。编译器无需检查* p是否* p是常量。我认为这是一种灵活的c / c ++语言,更好的方法是避免使用指针。