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

C语言中为何允许通过指针修改常量?实测无报错问题咨询

为什么C语言中能通过指针修改常量?

嘿,这个问题问到点子上了,咱们来把这个现象拆解清楚:

首先得明确一个核心点:C语言里的const关键字本质上是编译期的只读约束,它是告诉编译器「这个变量的内容不应该被直接修改」,而不是强制把变量放到硬件层面的只读内存区域。这也是你能通过指针绕开修改的根本原因。

你的代码里的几个关键细节

先看你的测试代码:

int main( int argc, char ** argv ) { 
    const int my_const = 9; 
    int *ptr = &my_const; 
    *ptr += 10; 
    printf("%d", my_const); 
    return 0; 
}
  1. 类型转换的警告:int *ptr = &my_const;这行其实是把const int*类型的指针赋值给了int*,这违反了C标准的类型限定符规则。如果你开启了gcc的高警告等级(比如-Wall),gcc 4.7应该会输出类似「discards qualifiers from pointer target type」的警告——编译器已经在提醒你这么做有风险,但默认情况下它不会直接报错阻止编译。
  2. 局部const变量的存储位置:你定义的my_const是局部变量,它存储在栈内存中(栈是可读写的)。而全局的const变量通常会被编译器放到只读数据段(.rodata),如果尝试修改全局const变量,大概率会触发段错误(程序崩溃)。但局部const变量在栈上,硬件没有阻止写入,所以指针修改能成功。

这是编译器特定行为吗?

严格来说,这属于未定义行为(Undefined Behavior),C语言标准没有规定这种情况的结果必须是什么,不同编译器、不同优化等级、不同平台都可能给出不同的结果:

  • 当你用gcc 4.7默认无优化编译时,编译器会从内存中读取my_const的值,所以修改后输出19;
  • 如果开启优化(比如-O2),编译器会认为const变量的值不会被修改,直接把9这个常量值嵌入到printf的代码里,此时即使你通过指针修改了内存,输出结果还是9;
  • 换其他编译器(比如Clang)或者更新版本的gcc,可能会有不同的处理方式,甚至直接在编译阶段就更严格地阻止这种转换。

总结一下

  • const是给编译器的提示,不是内存级别的强制保护;
  • 通过指针修改const变量是未定义行为,结果不可预期;
  • 编译时开启高警告等级(-Wall -Wextra)能提前发现这种危险操作,避免后续的奇怪问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:47:20