为什么两个 const int 对象在转换后具有相同的地址"const"但值不同?



请参阅,我通过引用定义了const int & a = 1,并强制指针将pa转换为a,并通过更改pa来更改a的值。这是成功的。

但是,当定义了const int k = 1并且重复上述操作时,尽管pkk是相同的地址,但是* pkk不是相同的值。

它背后的原理是什么?

当我这样做的时候,你能解释一下IDE是如何处理内存分配的吗?

const int &a = 1;
int *pa = (int*)&a;
cout << &a << endl;
cout << pa << endl;
*pa = 2;
cout << a << endl;
//And here is the outcome.

//0x7ffeeb5d8a24
//0x7ffeeb5d8a24
//2

因此,我们成功地更改了a


const int k = 1;
cout << &k << endl;
int *pk = (int*)&k;
cout << &k << endl;
cout << pk << endl;
*pk = 2;
cout << *pk << ' ' << k;
//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//0x7ffeeb5d8a14
//2 1
//Process finished with exit code 0

这里的*pkk地址相同,但值不相同!这怎么会发生?

这在技术上是未定义的行为。在运行时修改const数据是不安全的,即使去掉了它的常量也是如此。只有最初不是const并且后来添加了const的数据才能安全地丢弃该const

但是,为了解释为什么您看到的输出让您感到困惑,答案是编译器优化

编译器将const int k = 1;视为编译时间常数,并假定k永远不会更改值(这是正确的!(。当编译器看到cout << *pk << ' ' << k;时,允许在编译时在调用站点用值1替换k,因此无论在运行时对k做了什么,您实际上都在执行cout << *pk << ' ' << 1;。但是,由于k是一个编译时常数,您可以获取它的地址,它必须存储在内存中,编译器可以自由地(很可能会(将该值存储在只读内存中。在运行时更改这样的内存可能会使您的应用程序崩溃,但这并不能保证

最新更新