ARTICLE DETAIL

资讯详情

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

cppcheck returnByReference 检查详解:函数按值返回大对象时的性能告警

cppcheck returnByReference 检查详解:函数按值返回大对象时的性能告警 开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载本篇文章聚焦 cppcheck 的性能类检查项returnByReference讲解该检查的触发条件、工作原理、修复方式以及它在 cppcheck 源码与测试中的实现细节。阅读完成后你将能够理解 cppcheck 如何识别getter 按值返回大成员这种不必要的拷贝场景掌握const修复写法并了解该检查的启用方式与局限性。检查项概览属性值MessageFunction returns a copy instead of returning by const reference.CategoryPerformanceSeverityPerformanceLanguageC该检查属于 lib/checkclass.cpp 中的类检查CheckClass模块是 cppcheck 面向 C 代码的众多性能建议之一。它在 lib/checkers.cpp 中被登记为{CheckClass::checkReturnByReference,performance}在启用了 performance 级别检查时生效。触发场景与核心问题在 C 中一个 getter 函数如果按值by value返回一个较大的成员对象例如容器或字符串那么每一次调用都会完整拷贝该成员的全部内容。即使调用方往往只是读取这个已经存放在对象内部的成员拷贝依然会发生造成不必要的性能开销。例如#include string struct S { std::string s; std::string getS() const { return s; } // - returnByReference: copies s on every call };每次调用getS()都会把s的内容完整复制一份在多数实现下还可能伴随内存分配而调用方通常只是想看一下这个成员。将其改为返回const引用即可彻底避免拷贝#include string struct S { std::string s; const std::string getS() const { return s; } };改动后函数返回的是对象内部成员s的只读视图不再产生任何数据拷贝。检查的判定逻辑源码视角从 lib/checkclass.cpp 的实现可以还原出 cppcheck 对该场景的完整判定流程入口守卫仅当performance级别已启用时才执行检查lib/checkclass.cpp。遍历所有类/结构体作用域对classAndStructScopes中的每个类遍历其函数列表lib/checkclass.cpp。排除不合适的目标函数返回指针returnsPointer、返回引用returnsReference、返回标准类型returnsStandardType的函数直接跳过——它们本来就不会触发拷贝问题隐式虚函数isImplicitlyVirtual跳过避免对虚接口的误报运算符重载isOperator跳过被取地址的函数指针用法functionPointerUsage跳过返回视图类容器如std::string_view之类的view容器跳过因为视图本身就代表引用语义非const且带右值引用限定符的函数跳过——这类方法可能被临时对象调用按值返回更安全lib/checkclass.cpp。提取单一返回的成员变量通过getSingleReturnVar()lib/checkclass.cpp判断函数体是否就是return 某成员;这种单一语句形态且返回表达式最终指向一个类成员。依据类型与大小决定是否告警若返回的是非 view 的容器如std::string、std::vector直接告警若返回的是普通类对象则根据其ValueType::getSizeOf()估算的对象大小与2 * sizeof(pointer)比较只有对象足够大超过两倍指针大小才告警lib/checkclass.cpp。告警最终由returnByReferenceError()lib/checkclass.cpp以如下格式输出[file:line]: (performance) Function getS() should return member s by const reference. [returnByReference]与同类检查的关系cppcheck 的类检查族还包含其他与拷贝/引用相关的性能检查可以配合使用passedByValue建议将按值传入的参数改为const引用对应 lib/checkother.cpp 中的消息文案redundantCopy / passByReference针对局部冗余拷贝的提示登记在 lib/checkers.cpp。returnByReference 关注的是函数返回方向的拷贝与上述参数传递方向的检查正好互补。测试用例印证在 test/testclass.cpp 的returnByReference()测试中覆盖了该检查的多个典型场景基本触发T getT() const { return t; }成员是 10 个int的数组类型T与std::string getS() const { return s; }均被报告而返回普通int的int getI() const { return i; }不报告test/testclass.cpp——印证了按类型/大小筛选的逻辑。虚函数不误报覆盖override的虚函数不被报告test/testclass.cpp。返回函数参数不报告std::string f(std::string s) { return s; }不报告——检查明确排除了参数成员lib/checkclass.cpp。右值引用限定不报告std::string foo() { return s; }用于临时对象时按值返回不被报告test/testclass.cpp。深层成员也能识别通过指针成员访问的mS1-str、mS1-mT.strT均能触发test/testclass.cpp说明getSingleReturnVar()会沿 AST 解开.与-直到定位到真正的成员。临时对象的成员不触发return t.temp().str;temp()返回临时对象不报告而return t.s[0].str;数组成员会报告test/testclass.cpp——返回临时对象的成员时按值拷贝是安全的。测试通过checkReturnByReference_辅助函数test/testclass.cpp构造settingsBuilder().severity(Severity::performance).library(std.cfg)环境来运行这也提示我们该检查依赖标准库配置std.cfg来识别std::string等容器类型。如何启用该检查由于 returnByReference 的 Severity 是 performance启用方式与 cppcheck 其他性能检查一致# 启用全部 performance 级别检查returnByReference 包含在内 cppcheck --enableperformance src.cpp # 启用绝大多数检查error 恒开启其余可选级别全部打开 cppcheck --enableall src.cpp--enableperformance对应源码中的severity.enable(Severity::performance)分支lib/settings.cpp检查入口处也做了双重判定只要Severity::performance被启用即执行lib/checkclass.cpp。建议在开启该检查时同时加载标准库配置默认已加载 cfg/std.cfg否则std::string、std::vector等容器类型可能无法被识别为容器导致检查效果受限。修复注意事项修复时把按值返回改为返回const是安全的因为 getter 通常返回的是对象内部已存在的成员其生命周期与对象一致。但需要注意以下边界情况cppcheck 也已针对这些场景做了豁免不要用于临时对象/右值场景若函数可能被临时对象调用如带限定符返回引用会悬垂cppcheck 对该场景不告警虚函数接口改变虚函数的返回类型会破坏派生类覆盖关系cppcheck 对隐式虚函数不告警视图类容器std::string_view这类视图本身已是引用语义无需再改。总而言之returnByReference 是 cppcheck 在 C 性能检查上的一个典型实践通过返回单一成员 类型/大小判定 虚函数/右值/临时对象豁免的组合逻辑精准定位 getter 中的按值拷贝并以const修复作为标准建议。赞分享开发工具静态分析代码质量质量保障【免费下载链接】cppcheckstatic analysis of C/C code项目地址https://gitcode.com/gh_mirrors/cpp/cppcheck点击查看免费下载相关推荐Cppcheck CastAddressToIntegerAtReturn 检查器详解修复函数返回值中的指针与整数混用Cppcheck CastAddressToIntegerAtReturn 检查器详解修复函数返回值中的指针与整数混用 本指南深入讲解 Cppcheck 的开发工具静态分析代码质量质量保障cppcheck passedByValue 检查器深度解析C 函数参数按值传递的性能告警与修复实践cppcheck passedByValue 检查器深度解析C 函数参数按值传递的性能告警与修复实践 导读 passedByValue 是 cppchec开发工具静态分析代码质量质量保障cppcheck copyCtorAndEqOperator 检查详解拷贝构造函数与 operator 不成对定义的正确性告警cppcheck copyCtorAndEqOperator 检查详解拷贝构造函数与 operator 不成对定义的正确性告警 导读 copyCtorA开发工具静态分析代码质量质量保障上一篇如何快速掌握NVIDIA显卡优化免费专业级NVIDIA Profile Inspector终极配置指南下一篇MikroORM 的 wrap() 辅助函数完全指南实体状态、关系加载、序列化与 assign() 数据更新创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表