C语言指针与索引疑问:静态代码检查器为何报数组越界?
解答:C-STAT静态代码检查器误报数组越界的问题
先明确:已确认这是代码检查器C-STAT的bug(正如你在评论里提到的)。下面针对你的疑问逐一分析:
你的代码示例(整理后)
typedef struct { int16_t signalOrig; } TT; typedef struct { int iii; // <-- 注:改为int16_t则无警告! uint16_t numCalibPairs; TT calib[5]; } SS; void Test(const SS* sensorConf); void Test(const SS* sensorConf) { const int16_t f = sensorConf->calib[0].signalOrig; }
你的疑问解答
1. 为什么提示“数组指针”?
这是C-STAT的类型解析错误——它错误地将指向SS结构体的指针sensorConf,识别成了指向数组的指针。正常情况下,sensorConf是结构体指针,而非数组指针,检查器在这里混淆了两种指针的类型定义,属于逻辑bug。
2. 为什么认为索引是[8,8]?
结合你补充的细节(调整成员类型/数量后警告消失),这是检查器对结构体成员偏移计算错误导致的:
- 在ARM Cortex-M4环境中,
int是4字节,uint16_t是2字节,前两个成员总大小是6字节;加上结构体的4字节对齐规则,会自动填充2字节,使得calib数组相对于结构体起始地址的偏移量是8字节。 - 检查器完全搞混了「结构体成员的字节偏移」和「数组索引」的概念,把
calib[0]的偏移量8字节,误当成了数组的索引值[8,8],进而判定超出数组边界。
3. 是检查器的问题还是我的代码问题?
完全是检查器的bug,你的代码没有任何问题:
- 你访问的
calib[0]是长度为5的数组的第一个元素,索引完全在合法范围[0,4]内; - 你验证的几个场景(移除前两个成员之一、把
iii改成int16_t、数组前保留4字节)都能让警告消失,这直接证明了问题出在检查器对结构体成员偏移的计算逻辑上——当数组前的成员总字节数(含对齐)刚好是4字节时,它的计算逻辑“凑巧”正确,不会误报;一旦偏移量不符合它的预期,就会触发错误的越界判断。
内容的提问来源于stack exchange,提问作者Ernie Mur




