cppcheck启用style检查,抑制HAL回调噪音,更新使用说明

This commit is contained in:
2026-09-01 13:37:54 +08:00
parent ed81a97442
commit 3fdfeff1fd
2 changed files with 45 additions and 14 deletions
+5 -1
View File
@@ -41,10 +41,14 @@ repos:
- id: cppcheck - id: cppcheck
name: cppcheck name: cppcheck
entry: cppcheck entry: cppcheck
args: [--enable=warning,performance,portability, --error-exitcode=1, args: [--enable=warning,performance,portability,style, --error-exitcode=1,
--std=c99, --quiet, --std=c99, --quiet,
--suppress=missingIncludeSystem, --suppress=missingInclude, --suppress=missingIncludeSystem, --suppress=missingInclude,
--suppress=invalidPrintfArgType_sint, --suppress=invalidPrintfArgType_uint, --suppress=invalidPrintfArgType_sint, --suppress=invalidPrintfArgType_uint,
--suppress=unusedFunction, --suppress=unusedStructMember,
--suppress=noExplicitConstructor, --suppress=useStlAlgorithm,
--suppress=constParameterPointer, --suppress=constParameterCallback,
--suppress=constVariablePointer,
-I Inc -I App -I Drivers/BSP, -I Inc -I App -I Drivers/BSP,
-I Drivers/STM32F4xx_HAL_Driver/Inc -I Drivers/CMSIS/Include, -I Drivers/STM32F4xx_HAL_Driver/Inc -I Drivers/CMSIS/Include,
-I Middlewares/Third_Party/FreeRTOS/Source/include] -I Middlewares/Third_Party/FreeRTOS/Source/include]
+40 -13
View File
@@ -94,15 +94,15 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
| 类别 | 含义 | 典型问题 | | 类别 | 含义 | 典型问题 |
|---|---|---| |---|---|---|
| `warning` | 通用警告 | 变量未使用、除零风险、空指针解引用、 unreachable code | | `warning` | 通用警告 | 变量未使用、除零风险、空指针解引用、unreachable code |
| `performance` | 性能问题 | 不必要的值拷贝、字符串重复查找、低效的函数调用 | | `performance` | 性能问题 | 不必要的值拷贝、字符串重复查找、低效的函数调用 |
| `portability` | 可移植性问题 | 不同平台行为不一致的代码、隐式类型转换 | | `portability` | 可移植性问题 | 不同平台行为不一致的代码、隐式类型转换 |
| `style` | 代码风格 | 变量作用域过大、冗余赋值、恒假条件、switch 缺 default |
#### 不开启的常见类别 #### 不开启的常见类别
| 类别 | 为什么不开 | | 类别 | 为什么不开 |
|---|---| |---|---|
| `style` | 太多噪音(未使用函数、未用参数),会淹没真正问题 |
| `error` | 严重错误(数组越界、内存泄漏),cppcheck 默认已包含,不需要显式加 | | `error` | 严重错误(数组越界、内存泄漏),cppcheck 默认已包含,不需要显式加 |
| `information` | 信息类(未解析的头文件等),无实际价值 | | `information` | 信息类(未解析的头文件等),无实际价值 |
@@ -112,12 +112,37 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
--std=c99 # 按 C99 标准检查(Keil 工程常用) --std=c99 # 按 C99 标准检查(Keil 工程常用)
--error-exitcode=1 # 发现问题返回非零退出码(pre-commit 用来拦截提交) --error-exitcode=1 # 发现问题返回非零退出码(pre-commit 用来拦截提交)
--quiet # 只报问题,不显示扫描进度 --quiet # 只报问题,不显示扫描进度
--suppress=missingInclude # 抑制"找不到头文件"(HAL/CMSIS 路径在 Keil 工程配置里,cppcheck 不知道)
--suppress=invalidPrintfArgType_sint # printf 的 %d 传 uint32_t —— 实际安全,非真正缺陷 # --- 必须抑制(误报/不可修改) ---
--suppress=invalidPrintfArgType_uint # printf 的 %u 传 int —— 实际安全,非真正缺陷 --suppress=missingInclude # HAL/CMSIS 路径在 Keil 工程配置里,cppcheck 不知道
-I Inc -I App -I Drivers/BSP # 指定头文件搜索路径,让 cppcheck 能解析 #include --suppress=invalidPrintfArgType_sint # printf 的 %d 传 uint32_t —— 实际安全
--suppress=invalidPrintfArgType_uint # printf 的 %u 传 int —— 实际安全
--suppress=constParameterPointer # HAL 回调签名固定(如 SPI_HandleTypeDef*),不能加 const
--suppress=constParameterCallback # 回调函数指针类型限制,不能改签名
--suppress=unusedFunction # 第三方库回调/弱符号函数被误报为未使用
--suppress=unusedStructMember # HAL 寄存器位域成员未显式使用
--suppress=noExplicitConstructor # C++ 兼容,不影响纯 C
--suppress=useStlAlgorithm # C++ STL 相关,不影响纯 C
# --- 暂时抑制(噪音多,后续可移除) ---
--suppress=constVariablePointer # 局部指针加 const 是好习惯,但当前改动量大
# --- 头文件路径 ---
-I Inc -I App -I Drivers/BSP
-I Drivers/STM32F4xx_HAL_Driver/Inc -I Drivers/CMSIS/Include
-I Middlewares/Third_Party/FreeRTOS/Source/include
``` ```
#### 抑制规则说明
| 抑制规则 | 原因 | 是否永久 |
|---|---|---|
| `constParameterPointer` | HAL 回调签名由驱动框架定义,用户不能改 | 永久 |
| `constParameterCallback` | 同上,回调函数指针类型受限 | 永久 |
| `constVariablePointer` | 局部指针加 const 是好习惯,但当前代码量大、改动多 | 暂时 |
| `unusedFunction` | CubeMX 生成的弱符号、第三方库回调被误报 | 永久 |
| `unusedStructMember` | HAL 寄存器位域按位操作,cppcheck 不理解 | 永久 |
#### 扫描范围 #### 扫描范围
通过 `types: [c]` + `exclude` 控制: 通过 `types: [c]` + `exclude` 控制:
@@ -138,15 +163,17 @@ MDK-ARM/ # Keil 工程文件
test/ # 测试代码 test/ # 测试代码
``` ```
#### 如何抑制误报 #### style 检查发现的有价值问题(待修复)
如果 cppcheck 对某段代码报了误报,在 `.pre-commit-config.yaml` 的 cppcheck `args` 中添加: 开启 style 后,以下问题值得修复(符合嵌入式C代码规范):
```yaml | 规则 | 问题 | 涉及文件 | 价值 |
args: [--suppress=规则名, ...] |---|---|---|---|
``` | `knownConditionTrueFalse` | 条件恒假(`uint16_t > 65535`) | net_socket.c | **高**:潜在 Bug |
| `compareValueOutOfTypeRangeError` | 同上 | net_socket.c | **高**:潜在 Bug |
常用可抑制规则:`uninitvar`(未初始化变量,但你确定后续会赋值)、`knownConditionTrueFalse`(条件恒真/假,但你故意这么写)。 | `redundantAssignment` | 重复赋值覆盖旧值 | ch395f.c | **高**:Bug 嫌疑 |
| `unreadVariable` | 变量赋值后未读取 | gd5f2gq5ue.c, time_sync.c, ringbuf.c | **中**:冗余代码 |
| `variableScope` | 变量作用域可缩小 | sys_clock.c, net_socket.c 等 | **低**:规范6.1,可逐步修 |
#### 日常速度 #### 日常速度