Cppcheck检测动态数组越界:GPIO初始化代码报错原因解析
Cppcheck报数组越界错误的原因解析
问题场景
以下GPIO初始化代码编译正常且运行无问题:
typedef enum { USER_LED = 0, DEBUG_UART_TX, DEBUG_UART_RX, TOTAL_IO_PINS, } gpio_pin; typedef struct { GPIO_PRT_Type *port; uint32_t pin; uint8_t drive_mode; uint8_t hsio; // high speed io matrix/multiplexer } st_gpioconfig; st_gpioconfig gpio_configuration_array[] = { { GPIO_PRT13, P13_7_PIN, CY_GPIO_DM_STRONG_IN_OFF, HSIOM_SEL_GPIO }, { GPIO_PRT5, P5_1_PIN, CY_GPIO_DM_STRONG_IN_OFF, P5_1_SCB5_UART_TX }, { GPIO_PRT5, P5_0_PIN, CY_GPIO_DM_HIGHZ, P5_0_SCB5_UART_RX }, }; void gpio_init() { cy_stc_gpio_pin_config_t pinCfg; memset((void *)&pinCfg, 0, sizeof(pinCfg)); for (int i = 0; i < TOTAL_IO_PINS ; i++) { pinCfg.driveMode = gpio_configuration_array[i].drive_mode; pinCfg.hsiom = gpio_configuration_array[i].hsio; Cy_GPIO_Pin_Init(gpio_configuration_array[i].port, gpio_configuration_array[i].pin, &pinCfg); } }
但使用Cppcheck 1.84静态分析时,抛出如下错误:
[src/gpio.c:46]: (error) Array 'gpio_configuration_array[1]' accessed at index 2, which is out of bounds. [src/gpio.c:47]: (error) Array 'gpio_configuration_array[1]' accessed at index 2, which is out of bounds. [src/gpio.c:48]: (error) Array 'gpio_configuration_array[1]' accessed at index 2, which is out of bounds.
将数组声明改为st_gpioconfig gpio_configuration_array[TOTAL_IO_PINS]后,错误消失。
原因解析
这是Cppcheck 1.84的静态分析局限性导致的误报:
- 数组大小推导的时机问题:当用
[]声明数组并初始化时,编译器会根据初始化列表的元素个数(此处为3个)确定数组大小为3。但Cppcheck在分析时,未正确关联TOTAL_IO_PINS的枚举值(等于3)与数组实际大小。 - 枚举值与数组大小的关联失效:Cppcheck 1.84的数据流分析未追踪到
TOTAL_IO_PINS是枚举最后一个成员,其值恰好等于数组初始化元素个数。它错误判定数组大小为1,因此当循环索引到2时,触发越界误报。 - 显式指定数组大小的作用:显式声明数组大小为
TOTAL_IO_PINS后,Cppcheck能直接将数组大小与枚举值关联,确认循环终止条件i < TOTAL_IO_PINS不会超出数组边界,从而消除误报。
简单来说,旧版本Cppcheck在处理隐式大小数组与枚举常量的关联时,数据流分析不完善,无法识别两者数值匹配,导致误判。显式指定数组大小后,静态分析工具能明确数组可用范围,错误自然消失。
内容的提问来源于stack exchange,提问作者hariudkmr
相关产品推荐
相关产品推荐

