You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言const场景下直接访问变量与*(&i)的输出差异原因

现象原理说明

首先明确:你给出的测试代码本身属于C语言标准定义的未定义行为,出现10、20的输出差异是编译器优化的结果,不是C语言本身规定i和*(&i)语义有区别。

代码本身的违规点

  • 被const限定的变量,C语言标准禁止通过无const限定的指针修改它的值。你的代码里const int i = 10;定义了一个const整型对象,后续直接把&i赋值给非const指针int* pt1本身就属于类型限定符不匹配的违规写法,再通过*pt1 = 20修改const对象的内存值,已经触发未定义行为——这种情况下程序输出任何值、甚至直接崩溃都是符合标准的,编译器不需要为这类代码的运行结果做任何一致性保证。

输出10和20的直接原因

这个结果是常见编译器优化逻辑下的典型产物:

  1. 对于直接访问i的语句,编译器看到i是const限定、初始值固定为10的局部变量,会默认这个值永远不会被合法修改,因此做常量折叠优化:根本不生成读取i所在内存的指令,直接把立即数10作为参数传给printf,所以第一行输出固定是10,和i所在内存实际存了什么值没有关系。
  2. 对于*(&i)的写法,编译器没有做等价替换为i的优化:因为前面出现了取i地址、通过指针修改对应内存的操作,编译器会老老实实生成“取i的内存地址、解引用读取该地址存储值”的指令,这时候读到的就是你通过pt1强行写入内存的20,因此第二行输出20。

你可以自行编译验证:用gcc编译时加-O0参数关闭所有优化,两个printf大概率都会输出20;如果加-O2开高等级优化,编译器甚至会直接把*pt1 = 20这段无意义的违规代码删掉,两个printf都会输出10。

常见误区提醒

不要相信“const只是语法检查、本质是栈上变量可以随便改”的错误说法,C标准明确规定修改const对象是未定义行为,编译器可以基于“const对象值永远不变”做任意激进优化,依赖这类违规写法的运行结果没有任何可移植性。


内容的提问来源于stack exchange,提问作者Abhinandan Kushwaha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:18:21