ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

cppcheck functionConst 检查器详解:识别可声明为 const 的成员函数与 const 正确性实践

cppcheck functionConst 检查器详解:识别可声明为 const 的成员函数与 const 正确性实践 开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载本指南深入解析 cppcheck 的functionConst检查器——它用于识别不修改任何成员变量、因而在技术上可以声明为const的 C 成员函数。文章以 functionConst 官方文档 为主体脉络结合 lib/checkclass.cpp 中CheckClassImpl::checkConst的源码实现与 test/testclass.cpp 中的测试用例讲解其检测规则、误报边界、修复方式以及与之配套的 const-correctness 检查器家族。读完本文你将掌握functionConst的触发条件、如何正确修复告警、何时应当忽略该建议以及如何把该检查集成进日常的静态分析流程。检查器概览functionConst是 cppcheck 中属于Robustness健壮性类别的检查器用于 C 代码分析其基本信息如下项目值MessageTechnically the member function x can be constCategoryRobustnessSeverityStyleInconclusiveLanguageC该检查器识别那些没有修改任何成员变量、因此可以在技术上声明为const的成员函数。const成员函数承诺不修改对象状态并允许该函数在 const 对象上被调用。核心检测逻辑functionConst检查器逐一分析类作用域内的每个成员函数判断其是否满足可以变为const的条件。从源码 lib/checkclass.cpp 中CheckClassImpl::checkConst()的实现可以看到其检测流程包含以下关键步骤遍历所有类/结构体作用域通过符号数据库mSymbolDatabase-classAndStructScopes遍历每个类作用域再遍历其中的functionList。跳过无法建议 const 的函数非普通函数func.type ! eFunction或没有函数体!func.hasBody()的函数friend、static、virtual函数func.isFriend()、func.isStatic()、func.hasVirtualSpecifier()有函数指针用法func.functionPointerUsage的函数有右值引用限定符func.hasRvalRefQualifier()的函数。分析函数体调用checkConstFunc()lib/checkclass.cpp对函数体进行逐 token 扫描确认函数是否只读。checkConstFunc()的扫描逻辑是该检查器的核心它检测函数体内是否存在以下非 const行为对成员变量的写入如赋值操作、/--自增减操作Token::eIncDecOp、delete表达式等对流式输出流式写操作end-strAt(1) 非 const 成员函数调用调用其他非 const 成员函数时无法变为 const将成员变量作为可能被修改的参数传递当成员变量以指针或引用形式传给可能修改它的函数参数时argVar-isArrayOrPointer() || argVar-isReference()除非该参数本身为constSTL 容器的非 const 操作如对std::vector等非 const 容器的operator[]赋值等函数体中含有#ifdef条件编译mTokenizer-hasIfdef存在条件编译时无法确定完整语义直接放弃判定返回非 const 指针/引用源码中明确不建议对返回非 const 指针或引用的函数建议 const见 lib/checkclass.cpp 中isPointerOrReference与Function::returnsPointer/returnsReference的判断。同时如果函数体通过引用或指针修改外部传入的对象而非成员变量这不会阻止函数变为 const——文档中的copyDataTo示例正是这种情况。为什么这个告警是 InconclusivefunctionConst的严重级别为Style且标记为Inconclusive不确定。原因在于一个函数技术上可以成为 const并不代表它在概念上应该成为 const。文档明确指出其中的危险性const 成员函数允许对对象外部产生副作用。例如一个使用系统调用格式化硬盘的成员函数技术上完全可以声明为 const——因为它不修改任何成员变量——但这对 const 对象的使用者来说是一种语义欺骗const 对象的使用不应产生副作用。因此该检查器给出的信息是技术上可以将这个函数变为 const但请先思考设计是否合理。对于完全没有副作用的函数将其声明为 const 是推荐做法。从源码 lib/checkclass.cpp 中checkConstError2()的告警文本也能看到这一设计意图Technically the member function $symbol can be const. Even though the function can be made const function technically it may not make sense conceptually. Think about your design and the task of the function first - is it a function that must not change object internal state?这段信息以Certainty::inconclusive级别上报见 lib/checkclass.cpp并通过CWE398不良编码实践关联 CWE 编号。修复方法修复方式非常直接在函数签名之后添加const关键字表明该函数不修改对象状态。修复前class Rectangle { int width, height; public: int getWidth() { return width; } int getHeight() { return height; } int getArea() { return width * height; } void printInfo() { std::cout Width: width , Height: height std::endl; } bool isSquare() { return width height; } void copyDataTo(Rectangle other) { other.width width; other.height height; } };修复后class Rectangle { int width, height; public: int getWidth() const { return width; } int getHeight() const { return height; } int getArea() const { return width * height; } void printInfo() const { std::cout Width: width , Height: height std::endl; } bool isSquare() const { return width height; } void copyDataTo(Rectangle other) const { other.width width; other.height height; } };注意copyDataTo虽然修改了other对象的成员但other是通过引用传入的参数而非本对象的成员变量因此该函数依然可以合法地声明为const。告警输出格式从 test/testclass.cpp 的测试用例const1()可以看到实际告警输出格式class Fred { int a; int getA() { return a; } };输出[test.cpp:3:9]: (style, inconclusive) Technically the member function Fred::getA can be const. [functionConst]其中(style, inconclusive)表明这是不确定级别的风格建议。测试套件中还覆盖了大量边界场景嵌套类Fred::A::getA、运算符重载operator、operator[]、转换运算符operatorconst int*、返回 STL 容器的函数GetVec、GetPair、继承层级中的虚函数判断等见 test/testclass.cpp 附近的用例可用于理解检查器的能力边界。何时不应接受该建议文档的 Notes 部分给出了三条重要提醒该检查是不确定的将函数变为 const 的决定还应考虑概念设计——函数的职责是查询状态应当为 const还是执行动作可能不需要 const虚函数需要谨慎处理将虚函数改为 const 会影响整个继承体系。从源码 lib/checkclass.cpp 可以看到检查器会通过func.isImplicitlyVirtual(true, foundAllBaseClasses)检测函数是否为隐式虚函数若是则跳过如果无法确认基类信息告警文本会变为Either there is a missing override, or the member function $symbol can be const.见 lib/checkclass.cpp提示可能是漏写了override而非真的可以加 const。注意与functionStatic的联动如果函数既不访问成员变量也不访问成员函数检查器会转而建议声明为static源码 lib/checkclass.cpp 中suggestStatic memberAccessed ! MemberAccess::MEMBER对应告警为functionStatic级别为正常而非不确定。这属于同一分析流程的两个输出分支。相关检查器functionConst是 cppcheck const-correctness 检查家族中的一员与其他可以加 const类检查器互补检查器作用对象functionStatic可以声明为 static 的成员函数constParameter可以声明为 const 的函数参数constParameterReference可以声明为 const 的引用参数constParameterPointer可以声明为 const 的指针参数constVariable可以声明为 const 的局部变量constVariableReference可以声明为 const 的局部引用变量这些检查器共同帮助开发者系统性地提升代码的 const 正确性const-correctness。启用方式与运行环境functionConst属于 Style 级别的检查。在 cppcheck 中style 级别告警默认开启但不确定级别inconclusive的告警默认关闭需要通过--inconclusive选项启用# 启用不确定级别的告警functionConst 需要此选项才会输出 cppcheck --inconclusive yourfile.cpp也可以结合--enablestyle显式指定检查类别cppcheck --enablestyle --inconclusive yourfile.cpp需要注意的是从源码 lib/settings.cpp 可以看出functionConst同时出现在 premium 检查器列表中即该检查也可由 cppcheck premium 版本提供而在 lib/checkclass.cpp 中checkConst()的入口判断是只要 style 级别告警启用或 premium 的functionConst/functionStatic任一启用就执行该分析流程。此外 lib/checkclass.cpp 的注释还提到该检查存在历史误报issue #3322这也解释了其 inconclusive 定位的原因——建议使用者结合代码上下文人工复核后再采纳。总结functionConst是一个低风险、高收益的风格检查器它帮助开发者把只读成员函数的语义用const显式表达出来从而让函数的非修改性质在签名层面一目了然允许在 const 对象上调用这些函数提升整个代码库的 const 正确性帮助编译器进行优化向其他开发者传递更清晰的代码意图。使用时牢记三条原则技术上可行不等于概念上正确——优先思考函数职责是查询还是动作虚函数变更需评估整个继承体系对告警的人工复核是必要环节因为该检查本身被设计为 inconclusive。结合 functionStatic、constParameter 等配套检查器一起使用可以系统化地完成一轮完整的 const-correctness 代码审计。赞分享开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载相关推荐TinyMCE 7.5.0 版本深度解析color_map_raw 原始 CSS 配色、颜色选择器无障碍改进与 5 项关键修复TinyMCE 7.5.0 版本深度解析 color_map_raw 原始 CSS 配色、颜色选择器无障碍改进与 5 项关键修复 导读 TinyMCE 7.5开发工具静态分析代码质量质量保障Video2X5分钟用AI把老视频修到4KVideo2X5分钟用AI把老视频修到4K 模糊的根源放大只是拉伸像素 翻出手机里 2018 年录的视频放大一看满屏方块人脸糊成一片。Video2X开发工具静态分析代码质量质量保障Folly 中的 folly::Function 详解不可拷贝的多态函数包装器与 const 正确性Folly 中的 folly::Function 详解不可拷贝的多态函数包装器与 const 正确性 导读 folly::Function 是 Folly 开后端并发编程异步编程上一篇Preline UI轮播图组件完全指南打造现代化网站必备利器下一篇JuiceFS S3 网关深度解析实现文件系统的S3协议兼容创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表