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

scanf修改其他变量是BUG吗?GCC下给main加void参数为何可解决?

问题根因

这不是GCC的BUG,本质是你使用的mingw-w64默认链接的**微软旧版C运行时库(msvcrt.dll)**不支持C99标准新增的%hhd格式符导致的未定义行为:

  • 旧版msvcrt.dll识别不了%hhd,会把它当成%d处理,%d对应需要写入4字节的int类型空间
  • 你给scanf传的是char类型的指针,只有1字节的合法写入空间,scanf写4字节直接造成栈溢出,覆盖了栈上相邻的condition变量的内存内容
  • 每次执行scanf都会把condition的值冲成0,所以你每次condition++之后输出永远是1,循环永远不会退出

其他现象解释

  1. 为什么注释scanf就正常?
    没有了栈溢出操作,condition变量的自增逻辑不受干扰,自然按预期运行。
  2. 为什么Clang下运行正常?
    Clang的Windows版本通常默认使用适配C99标准的运行时库,能正确识别%hhd格式符,只会写入1字节到char空间,不会发生栈溢出。
  3. 为什么给main加void参数问题就消失?
    函数签名修改后,编译器会调整栈帧的内存布局、变量对齐规则,此时scanf溢出写入的4字节刚好没有覆盖到condition变量所在的内存,所以看起来问题消失了,但本质还是存在未定义行为,属于巧合的正常,不是真正修复了问题。

修复方案

可以任选以下一种方式彻底解决问题:

  • 把char choice改成int choice,配合%d格式符使用,避免短整型的格式兼容问题
  • 如果一定要用char类型存储,编译的时候给gcc加上-D__USE_MINGW_ANSI_STDIO=1参数,强制mingw使用自己实现的符合C99标准的格式化输入输出逻辑,就可以正确识别%hhd
  • 升级你的mingw-w64版本,新版本默认已经开启C99格式化支持,不会出现这个问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:15:03