自研支持指针与常量的编程语言:探究C语言常量内存存储机制
关于C语言中
const变量内存存储与修改行为的解惑 嘿,这个问题问到点子上了——很多刚深入C语言的开发者都会被const的表现搞懵,咱们把这个事儿掰碎了说:
首先得纠正一个常见误解:const在C里不是“把变量锁死在只读内存”的关键字,它本质是一个编译期只读限定符。它的核心作用是告诉编译器:“请阻止我直接修改这个变量”,但并不强制要求操作系统把它放到只读内存区域——这得看变量的存储类别。
先看你的代码里的关键问题
你这段代码其实触发了未定义行为(Undefined Behavior),虽然当前环境下输出了2,但换个编译器、开个优化选项,结果可能完全不一样:
#include <stdio.h> int main (int argc, char ** argv) { const int x = 1; int *y; y = &x; // 这里编译器应该抛出警告:把const指针转成非const指针是违反类型规则的 *y += 1; // 这里是标准明确的未定义行为! printf("x = %d\n", x); }
不同const变量的存储差异
全局/静态
const变量
这类变量通常会被编译器放到只读数据段(.rodata),操作系统会标记这段内存为不可写。如果你尝试用指针修改这类变量,会直接触发段错误(比如Linux下的SIGSEGV)——这就是你看到“运行时常量存储于只读内存”的场景,这个说法是对的,但仅限全局/静态const变量。局部
const变量(栈上的const)
你代码里的x就是这类变量:它是在函数栈帧里分配的,栈内存本身是可写的。所以你通过强制类型转换绕过编译器的const检查后,能修改成功是当前环境的“巧合”,但这完全不合法——标准允许编译器对这类变量做激进优化,比如直接把x替换成编译时常量1,这时候即使你通过指针改了栈上的值,printf输出的还是1。
总结一下
const的核心价值是编译期约束:帮你避免不小心的直接修改,同时给编译器提供优化线索。- 只有全局/静态
const变量才大概率会被放到只读内存,得到运行时写保护;局部const变量还是在栈上,可写(但修改它是未定义行为)。 - 你的代码能运行只是当前环境的表现,绝对不能依赖这种行为——在严肃的C代码里,这种写法是严重错误。
内容的提问来源于stack exchange,提问作者ClementNerma
相关产品推荐
相关产品推荐

