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

g++格式溢出检测机制:gcc对tm_mon范围识别及加1警告疑问

GCC sprintf缓冲区溢出警告的差异原因解析

场景1:直接使用tm_mon无警告的原因

对于代码:

char mm[3]; 
sprintf(mm, "%02d", date_struct->tm_mon); // tm_mon取值0到11

GCC的-Wformat-overflow静态分析机制会识别标准库结构体成员的既定范围:

  • struct tm的tm_mon是<time.h>定义的标准成员,C标准明确规定其取值范围为0到11
  • GCC内置的静态分析数据库预存了这个范围信息,因此能确定%02d格式化后只会输出两位数字(00到11),加上字符串结束符\0刚好占用3字节,完全匹配缓冲区mm的大小,不会触发溢出警告。

场景2:tm_mon+1触发警告的原因

对于代码:

char mm[3]; 
sprintf(mm, "%02d", date_struct->tm_mon+1);

GCC的静态分析无法对运算后的表达式做精确范围推导:

  • 尽管逻辑上tm_mon+1的范围是1到12,格式化后同样是两位数字,但静态分析工具采取保守策略:它不会将tm_mon的原始范围和加法操作结合做精准运算,而是默认tm_mon可能被其他代码篡改(脱离标准规定的0-11范围),导致tm_mon+1可能是任意int值(比如三位数的数值)
  • 这种情况下,%02d会输出超过2位的字符,加上结束符会超出mm的3字节容量,因此GCC触发"directive writing between 2 and 11 bytes into a region of size 3"的溢出警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:53:14