diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f17eb9b..89966985 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,10 +41,14 @@ repos: - id: cppcheck name: cppcheck entry: cppcheck - args: [--enable=warning,performance,portability, --error-exitcode=1, + args: [--enable=warning,performance,portability,style, --error-exitcode=1, --std=c99, --quiet, --suppress=missingIncludeSystem, --suppress=missingInclude, --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 Drivers/STM32F4xx_HAL_Driver/Inc -I Drivers/CMSIS/Include, -I Middlewares/Third_Party/FreeRTOS/Source/include] diff --git a/docs/pre-commit使用说明.md b/docs/pre-commit使用说明.md index 61c46372..dbcbe7da 100644 --- a/docs/pre-commit使用说明.md +++ b/docs/pre-commit使用说明.md @@ -94,15 +94,15 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法 | 类别 | 含义 | 典型问题 | |---|---|---| -| `warning` | 通用警告 | 变量未使用、除零风险、空指针解引用、 unreachable code | +| `warning` | 通用警告 | 变量未使用、除零风险、空指针解引用、unreachable code | | `performance` | 性能问题 | 不必要的值拷贝、字符串重复查找、低效的函数调用 | | `portability` | 可移植性问题 | 不同平台行为不一致的代码、隐式类型转换 | +| `style` | 代码风格 | 变量作用域过大、冗余赋值、恒假条件、switch 缺 default | #### 不开启的常见类别 | 类别 | 为什么不开 | |---|---| -| `style` | 太多噪音(未使用函数、未用参数),会淹没真正问题 | | `error` | 严重错误(数组越界、内存泄漏),cppcheck 默认已包含,不需要显式加 | | `information` | 信息类(未解析的头文件等),无实际价值 | @@ -112,12 +112,37 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法 --std=c99 # 按 C99 标准检查(Keil 工程常用) --error-exitcode=1 # 发现问题返回非零退出码(pre-commit 用来拦截提交) --quiet # 只报问题,不显示扫描进度 ---suppress=missingInclude # 抑制"找不到头文件"(HAL/CMSIS 路径在 Keil 工程配置里,cppcheck 不知道) ---suppress=invalidPrintfArgType_sint # printf 的 %d 传 uint32_t —— 实际安全,非真正缺陷 ---suppress=invalidPrintfArgType_uint # printf 的 %u 传 int —— 实际安全,非真正缺陷 --I Inc -I App -I Drivers/BSP # 指定头文件搜索路径,让 cppcheck 能解析 #include + +# --- 必须抑制(误报/不可修改) --- +--suppress=missingInclude # HAL/CMSIS 路径在 Keil 工程配置里,cppcheck 不知道 +--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` 控制: @@ -138,15 +163,17 @@ MDK-ARM/ # Keil 工程文件 test/ # 测试代码 ``` -#### 如何抑制误报 +#### style 检查发现的有价值问题(待修复) -如果 cppcheck 对某段代码报了误报,在 `.pre-commit-config.yaml` 的 cppcheck `args` 中添加: +开启 style 后,以下问题值得修复(符合嵌入式C代码规范): -```yaml -args: [--suppress=规则名, ...] -``` - -常用可抑制规则:`uninitvar`(未初始化变量,但你确定后续会赋值)、`knownConditionTrueFalse`(条件恒真/假,但你故意这么写)。 +| 规则 | 问题 | 涉及文件 | 价值 | +|---|---|---|---| +| `knownConditionTrueFalse` | 条件恒假(`uint16_t > 65535`) | net_socket.c | **高**:潜在 Bug | +| `compareValueOutOfTypeRangeError` | 同上 | net_socket.c | **高**:潜在 Bug | +| `redundantAssignment` | 重复赋值覆盖旧值 | ch395f.c | **高**:Bug 嫌疑 | +| `unreadVariable` | 变量赋值后未读取 | gd5f2gq5ue.c, time_sync.c, ringbuf.c | **中**:冗余代码 | +| `variableScope` | 变量作用域可缩小 | sys_clock.c, net_socket.c 等 | **低**:规范6.1,可逐步修 | #### 日常速度