Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “参考运算符”的结果是什么&&引用;关于常量变量?_C++_C_Operators_Constants - Fatal编程技术网

C++ “参考运算符”的结果是什么&&引用;关于常量变量?

C++ “参考运算符”的结果是什么&&引用;关于常量变量?,c++,c,operators,constants,C++,C,Operators,Constants,有人问我如何更改常量变量的值 我明显的回答是“指针!”但我尝试了下一段代码,我感到困惑 int main() { const int x = 5; int *ptr = (int *)(&x); // "Cast away" the const-ness.. cout << "Value at " << ptr << ":"<< (*ptr) <<endl; *ptr = 6; cout

有人问我如何更改常量变量的值

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

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;
}
intmain()
{
常数int x=5;
int*ptr=(int*)(&x);/“丢弃”常数。。

cout可能您正在经历代码优化的副作用,尝试通过禁用所有优化来运行相同的代码,或者检查asm生成的代码。我猜编译器正在沿着函数重用它在某个注册表中的值,因为他打赌常量,所以即使您实际更改了值,更改的值也不是propagated正确。正如Keith在comemnts中注意到的,原因是您正在使用未定义的行为。

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

首先,这种行为是未定义的。也就是说,可能发生的情况如下:

执行此操作时:

int *ptr = (int *)(&x);
5
存储在某处的某个地址。这就是指针似乎工作正常的原因。(尽管丢弃常量仍然是未定义的行为)

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

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

cout您的程序调用未定义的行为(通过指针写入常量变量是未定义的行为),因此任何事情都可能发生。这是您在特定实现中看到的行为的最可能的解释:


当您执行
&x
时,您确实会得到
&x
的地址。当您执行
*ptr=6
时,您会将6写入
x
的内存位置。但是当您执行
时,从
&x
返回的是指向const int的指针(即
int const*
).现在指针被inded实现为保存地址,但指针不是地址,您的示例很好地说明了原因:指针的类型尽管在运行时不存在,但仍然起着重要作用


在您的例子中,您正在舍弃常量,因此向编译器撒谎“此指针指向一个非常量int”。然而,编译器从声明中知道,
x
的值不能更改(它被声明为常量),并自由地利用了这一事实(标准允许这样做:您试图通过指向non-const int的指针来更改它是未定义的行为,因此编译器可以执行任何操作)。

看起来像是一种“优化”对我来说,
x
可能只是在可能的情况下被
5
取代。在调试模式下也会发生同样的事情吗?你是否意识到行为是未定义的,没有任何解释会在实现之间准确无误?想象一下,如果你定义了
#x5
。另外,除了一个谜题之外,希望不用多说……嗯更改常量的方法是删除“const”。但是你没有回答这个问题。#define宏的结果是什么?@mike:如果他真的
#define X 5
,写
&X
会导致编译器错误。我如何在VS2010上禁用优化?很可能你是对的。不一定可以禁用所有优化。编译器没有义务提供引用
x
实际上检索存储在
x
地址的内存中的任何内容的一种模式。程序的行为是未定义的;不要浪费时间试图让它做你想让它做的事情。如果你想更改
x
,你不应该让它成为
常量关于如何更改常量的想法…仅此而已:)我不是一个忍者…@Avrahamshuk:知道如何更改声明为
const
的变量对于跟踪bug非常有用。如果
const
-声明对象的值似乎正在更改,那么知道是什么导致了它非常有用,这样您就可以修复bug。(在一些非常罕见的情况下,如果出于某种原因更改变量的定义是不切实际的,那么故意这样做可能会有一定的意义。但是正如您所看到的,优化可以阻止这种尝试。它不需要将其缓存在寄存器中。因为
x
声明为
const
,所以它可以简单地替换
cout
cout << "But the value of x is still " << x <<endl;