参考运算符“&”的结果是什么?关于const变量?

时间:2011-11-13 22:05:05

标签: c++ c operators const

有人问我怎样才能改变const变量的值。

我明显的回答是"指针!"但我尝试了下一段代码,我感到困惑......

int main()
{
    const int x = 5;
    int *ptr = (int *)(&x); // "Cast away" the const-ness..
    cout << "Value at " << ptr << ":"<< (*ptr) <<endl;
    *ptr = 6;
    cout << "Now the value of "<< ptr << " is: " << (*ptr) <<endl;
    cout << "But the value of x is still " << x <<endl;
    return 0;
}

输出结果为:

Value at <some address> :5
Now the value of <same address> is: 6
But the value of x is still 5

现在,我不确定&#39;&amp; x&#39;但它绝对不是x的实际地址,因为x的值没有改变!

但总的来说,ptr 确实包含x的值! 那么,到底是什么?

使用VS2010编译

编辑

5 个答案:

答案 0 :(得分:15)

您的程序调用未定义的行为(通过指针写入const变量是未定义的行为),因此可能发生任何事情。这就是说,为什么你得到你在特定实现上看到的行为最可能的解释:

执行&x后,您的确会获得x的地址。执行*ptr = 6时,您会在x的内存位置写入6。但是当你执行cout << x时,实际上并没有从x的内存位置读取,因为编译器通过将x替换为5来优化代码。由于xconst,因此编译器可以这样做,因为没有合法的C ++程序会这样做会改变程序的行为。

答案 1 :(得分:2)

编译器在寄存器中缓存x,因此内存中的值会发生变化,但最后一次打印输出仍然相同。检查生成的程序集(使用-s编译)。

答案 2 :(得分:2)

首先,此行为未定义。也就是说,这是可能发生的事情:

执行此操作时:

int *ptr = (int *)(&x);

5存储在某处的某个地址。这就是指针似乎正常工作的原因。 (虽然抛弃const仍然是未定义的行为)

但是,由于编译器优化x = 5在最终的print语句中只是作为文字内联。编译器认为它是安全的,因为x被声明为const

cout << "But the value of x is still " << x <<endl;

这就是你打印原始值5的原因。

答案 3 :(得分:1)

也许您遇到代码优化的副作用,尝试通过禁用所有优化来运行相同的代码,或检查asm生成的代码。我猜编译器正在重复使用它在函数的某个注册表中的值,因为他打赌const,所以即使你实际上在改变值,改变的值也不会正确传播。 Keith在游戏中注意到的原因是你正在采取不明确的行为。

答案 4 :(得分:0)

&x返回的是指向const int的指针(即int const*)。现在指针被实现为保存地址,但指针 不是地址,你的例子显示了很好的原因:指针的类型,即使在运行时不存在,仍然起着重要的作用

在你的情况下,你正在抛弃const,因此向编译器说谎“这个指针指向一个非const int”。然而,编译器从声明中知道x的值不能改变(它被声明为const),并且可以自由地使用这个事实(并且标准允许它:你试图通过非指针来改变它) const int是未定义的行为,因此允许编译器执行任何操作。