ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

cppcheck redundantAssignInSwitch 检查器全解析:识别 switch 分支穿透导致的冗余赋值

cppcheck redundantAssignInSwitch 检查器全解析:识别 switch 分支穿透导致的冗余赋值 开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载redundantAssignInSwitch 是 cppcheck 中专门检测switch分支穿透fallthrough场景下冗余赋值的风格级检查器一个变量在某个case中被赋值随后在它穿透落入的后续case中被再次赋值覆盖而旧值在此期间从未被读取。本文将以 man/checkers/redundantAssignInSwitch.md 为骨架结合 lib/checkother.cpp 的源码实现与 test/testother.cpp 的测试用例完整讲解该检查器的触发条件、修复方法、实现原理与启用方式帮助你用它快速揪出switch中遗漏的break;与无效赋值。检查器速览属性值检查器 IDredundantAssignInSwitch报告消息Variable x is reassigned a value before the old one has been used.分类CategoryCode Quality代码质量严重级别SeverityStyle风格适用语言C/C关联 CWECWE-563Assignment to Variable without Use报告时消息会附带一句提示break; missing?直接暗示这是否是缺失break;的代码缺陷见 lib/checkother.cpp 中redundantAssignmentInSwitchError()的完整消息文本。问题本质case 穿透中的赋值覆盖该检查器描述的场景非常具体一个变量在某个switch的case中被赋值该值又在它穿透落入的后续case中被另一次赋值覆盖而中间从未读取过这个变量。换句话说这是一个写了值但从未被使用的赋值只是它恰好发生在switch的分支穿透语境里。用官方文档给出的最小复现代码来说明void bar(int); void foo(int a) { int y 1; switch (a) { case 2: y 2; // - falls through into case 3, missing break;? case 3: y 3; } bar(y); }当a 2时程序先执行y 2;由于case 2末尾没有break;控制流继续落入case 3y 3;随即把刚赋的值覆盖掉。y 2;产生的值从未被任何读取操作消费属于死代码同时强烈暗示作者可能忘记写break;。为什么值得修复官方文档给出的动机Motivation非常精准这是冗余赋值redundant assignment的switch 穿透变体通常是缺失break;的信号而非有意为之的穿透即使穿透确实是有意的第一个赋值仍然毫无意义——删掉它能让代码更清晰更重要的是switch穿透是 C/C 中一类典型的隐蔽错误来源漏写break;会导致多个分支执行同一段代码行为与作者意图完全不符。因此该检查器不仅是在做死代码清理更是帮助你在早期定位可能的控制流缺陷。标准修复方案官方文档给出的修复方式是在第一个case末尾补上break;阻断穿透void bar(int); void foo(int a) { int y 1; switch (a) { case 2: y 2; break; case 3: y 3; } bar(y); }修复后y 2;只会在a 2时执行并被bar(y)消费两个分支互不干扰。如果穿透是有意为之的例如多个case共享一段逻辑则应当删除前面那个冗余赋值并最好在代码中留下显式的 fallthrough 注释让意图一目了然。源码实现原理该检查器位于CheckOtherImpl::checkRedundantAssignment()中lib/checkother.cpp与普通冗余赋值检查器redundantAssignment、redundantInitialization共用同一入口只是按场景分流报告。核心流程如下前置开关判断仅当style严重级别被启用或 Premium 模式显式启用了redundantAssignment/redundantAssignInSwitch时才运行lib/checkother.cpp。遍历函数作用域通过SymbolDatabase::functionScopes遍历每个函数体逐个检查赋值运算符、等与自增/自减运算符/--表达式lib/checkother.cpp。排除干扰项跳过 RHS 为 0/NULL 的赋值、引用变量、静态变量、带自定义赋值运算符的类对象、智能指针等可能产生副作用或无法确定语义的场景lib/checkother.cpp。前向分析寻找下一次赋值调用FwdAnalysis::reassign()从当前赋值位置前向搜索同一变量被再次赋值的点期间会跟踪变量是否被读取。判定是否跨 case在两次赋值之间逐 token 扫描如果遇到case关键字则将hasCase置真若先遇到break或return则提前终止扫描lib/checkother.cpp。按场景分流报告hasCase为真时报告redundantAssignInSwitch否则区分初始化后被覆盖redundantInitialization与普通冗余赋值redundantAssignmentlib/checkother.cpp。报告时通过ErrorPath将两处赋值位置串联起来y is assigned→y is overwritten并以 CWE-563 关联便于在 IDE 或 CI 中呈现完整的问题链路lib/checkother.cpp。触发与不触发的边界条件从 test/testother.cpp 的switchRedundantAssignmentTest()与switchRedundantOperationTest()测试用例可以确认以下行为边界会触发该检查器的情形两个case依次对同一变量赋值且中间无break;基础场景第一个case内的赋值包在{ }块中、随后落入下一个case再次赋值第一次操作是y、--y、y、y--等自增自减之后落入下一个case被y 3;覆盖两次赋值之间夹有普通函数调用bar();只要该函数不读取y且不是noreturn仍会报告。不会触发的情形防误报设计两个case之间有break;、return、continue、throw等控制流终止语句两次赋值之间变量被真正读取过如printf(%d, y);或if (y) ...中间出现if条件分支内的赋值路径并不必然覆盖两次赋值针对的是不同变量连续两次都是自增/自减如y; y;因为它们不是值被覆盖goto跳转、strcpy/strncpy等缓冲区写入场景后者在测试中以TODO_ASSERT_EQUALS标记属于当前已知的未实现限制。如何启用与集成命令行启用该检查器隶属于style严重级别。由于checkRedundantAssignment()在style未启用时直接返回lib/checkother.cpp可用标准方式运行cppcheck --enablestyle your_file.cpp对单个文件或整个目录执行命中时输出形如[test.cpp:7:11] - [test.cpp:9:11]: (style) Variable y is reassigned a value before the old one has been used. break; missing? [redundantAssignInSwitch]其中-左侧为第一次赋值位置右侧为覆盖它的第二次赋值位置与测试断言格式完全一致test/testother.cpp。抑制与配置与其他检查器一致可通过行内注释// cppcheck-suppress redundantAssignInSwitch或命令行抑制规则忽略特定位置。在 lib/settings.cpp 中可以确认该检查器被纳入多个行业标准检查集CERT C、MISRA C:2012、MISRA C:2023、MISRA C:2023 等规则映射均包含redundantAssignInSwitch例如 MISRA C:2023 规则 0.1.1 与 MISRA C 规则 2.2见 lib/checkersidmapping.cpp 与 addons/misra.py因此在 MISRA/CERT 合规场景下它会被一并启用用于支撑无死代码类规则。相关检查器redundantAssignment —— 同一思想在switch之外的普通场景变量被赋值后、读取前就被完全覆盖同样属于 CWE-563 死代码范畴。redundantBitwiseOperationInSwitch ——switch中按位运算赋值的对应变体用于x | ...、x ...等复合按位赋值在 case 穿透中被重复执行的场景。赞分享开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载相关推荐cppcheck duplicateConditionalAssign 检查详解识别与 if 条件重复的冗余赋值cppcheck duplicateConditionalAssign 检查详解识别与 if 条件重复的冗余赋值 duplicateConditionalAs开发工具静态分析代码质量质量保障cppcheck overlappingStrcmp 检查器识别 strcmp 冗余比较导致的恒真条件cppcheck overlappingStrcmp 检查器识别 strcmp 冗余比较导致的恒真条件 导读 overlappingStrcmp 是 cppc开发工具静态分析代码质量质量保障Cppcheck redundantAssignment 检查器深度解析检测被覆盖前从未被读取的冗余赋值Cppcheck redundantAssignment 检查器深度解析检测被覆盖前从未被读取的冗余赋值 导读 本文深入解析 Cppcheck 静态分析器中开发工具静态分析代码质量质量保障上一篇ramsey/uuid 版本 2DCE Security UUID完全指南生成原理、自定义参数与源码剖析下一篇Teleport RFD 212 解析使用 jsonpath 插值处理任意 JSON OIDC Claims创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表