当我在MS VS C++ 2010上运行此代码时:
#include <iostream>
int main() {
const int a = 10;
const int *b = &a;
int *c = (int *)b;
*c = 10000;
std::cout << c << " " << &a << std::endl;
std::cout << *c << " " << a << " " << *(&a) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
0037F784 0037F784
10000 10 10
Run Code Online (Sandbox Code Playgroud)
编写该代码的动机是Stroustrup的"C++编程语言"中的这句话:"可以通过显式类型转换显式地删除对const指针的限制".
我知道尝试修改常量在概念上是错误的,但我觉得这个结果很奇怪.任何人都能解释其背后的原因吗?
让我们从显而易见的开始:其中一些是依赖于平台和编译器的.
首先,请参阅有关显式类型转换的这篇文章,特别是:
指向
const类型对象的指针可以转换为指向非const类型的指针.结果指针将引用原始对象.const类型的对象或对类型的对象的引用const可以被转换为对非const类型的引用.结果引用将引用原始对象.尝试通过这样的指针或引用修改该对象的结果将导致寻址异常,或者与原始指针或引用引用非const对象时相同.无论是否发生寻址异常,都取决于实现.
所以这就解释了为什么它可以让你在没有婊子的情况下修改变量.
请注意,您可以直接使用强制转换操作符来实现相同的操作,因为这就是编译器将为您执行的操作,如本文关于强制转换操作符所述,并给出了它们的优先顺序.
然而,这里真正的技巧是在内存模型中.静态分配的变量(如const int a)实际上可能永远不会在内存中具有任何"物理"位置,并且只是在编译时就地替换.(我试图把我的手指上这个实际的参考,但到目前为止,我可以抓住最近的和最好的是这个(很漂亮),这样回答到的内存分配,但从不使用一个静态变量? -如果任何人找到实际参考,请告诉我们.)
所以这里的编译器只是在幽默你,并试图尽可能多地理解你的指针运算,但最后会用a第二次cout调用的最后2个部分的实际值来代替.