关于在常量数据类型上使用const_cast的代码执行逻辑疑问
关于const_cast修改const变量的奇怪现象解析
嘿,我来给你拆解这段代码里的“诡异”行为,核心原因是编译器的常量折叠优化加上const_cast误用导致的未定义行为。
先看你贴的代码:
#include <iostream> int main() { const int i = 20; int *p = const_cast<int*>(&i); std::cout << "i:" << i << " *p:" << *p << " p:" << p << " &i:" << &i << std::endl; (*p)++; std::cout << "i:" << i << " *p:" << *p << " p:" << p << " ..." << std::endl; }
为什么会出现i和*p值不同但地址相同的情况?
常量折叠(Constant Folding):
当你定义const int i = 20;时,编译器把i识别为编译期常量。在编译阶段,它会直接把所有用到i的地方替换成字面量20,而不是程序运行时从i的内存地址读取值。所以第二个cout里的i,其实是硬编码的20,和内存里的实际值无关。指针操作的本质:
const_cast<int*>(&i)只是移除了指针的const属性,让你能通过指针修改内存地址里的内容,但i本身的const属性并没有被改变——C++标准明确规定,修改原本声明为const的变量是未定义行为(Undefined Behavior)。这里你通过(*p)++修改了&i指向的内存值(变成21),但cout输出i时,用的是编译期替换的20,而*p是从内存地址读取的实际值21,就出现了地址相同但值不同的“矛盾”现象。
额外提醒
如果把i改成非编译期常量,比如:
const int i = rand(); // 运行时才能确定值,编译器没法常量折叠
这时候修改*p后,i和*p的值会一致,但这依然是未定义行为——编译器完全可以生成让程序崩溃、输出乱码的代码,只是刚好在你的环境里看起来“正常”而已。
总结:永远不要用const_cast去修改原本声明为const的变量,这种操作没有任何保证,结果完全不可预测。
内容的提问来源于stack exchange,提问作者Sourav
相关产品推荐
相关产品推荐

