在使用sonarqube检测C++项目代码时,发现一个使用std::move引起的code smell等级的告警,特记录。

  • 原文内容:
  • Usually, when copying an object, the source object is unchanged, which means that all resources owned by the source objects have to be duplicated during the copy operation. In the case that the source object will no longer be used, this duplication is not efficient. Since C++11, a mechanism named move semantic has been added to detect such cases and replace the expensive copy by a much cheaper move operation that will steal resources.
  • The cornerstone of move semantic is the ability to detect during a “copy” if the source object will be reused or not. There are three situations:
    • The object is a temporary object, with no name, and if it can’t be named, it can’t be used
    • The object is used in some specific places, such as a return statement
    • The user explicitly promises to the compiler that he won’t care for the current value of the object any longer. He does so by using the specific cast operation named std::move.
  • If the user write std::move in one situation that is already handled by the first two cases, it has two drawbacks:
    • It is clumsy, useless code, which make understanding the code more complex
    • In some cases, it can decrease performances, because this can deactivate another optimization of the compiler, named copy elision.
  • When copy elision occurs, the object is neither copied nor moved (even if the copy/move constructors have side effects), in fact, the two objects are collapsed into only one memory location. When copy elision occurs is compiler-dependent, but is mandatory(强制性的) in the following cases:
    • in a return statement if the returned object is a prvalue of the same class type as the function return type
    • in the initialization of a variable if the initializer expression is a prvalue of the same class type as the variable type
  • This rule reports an issue(即检测出的code smell)when the use of std::move prevents the copy elision from happening.
  • Noncompliant Code Example
class A {};
A getA();A f() {A a = std::move(getA()); // Noncompliant, prevents copy elisionvector<A> v;v.push_back(std::move(getA())); // Noncompliantreturn std::move(a); // Noncompliant, prevents copy elision
}
  • Compliant Solution
class A {};
void test(A a);A f() {A a = getA(); // Compliantvector<A> v;v.push_back(getA()); // Compliantreturn a; // Compliant
}
  • 上面的核心内容就是,c++11标准提供的std::move函数如果使用不当,可能会导致copy elision(即std::move不但不能起到想要的作用,反而会阻碍编译器优化)。有两种方式一定会触发copy elision,其中之一便是:当return语句返回的对象是一个纯右值,且该对象类型与函数返回值类型相同时。

  • 相关链接:https://github.com/isocpp/CppCoreGuidelines/blob/036324/CppCoreGuidelines.md#Rf-return-move-local,这个github仓库包含的内容很值得一看,作者是大名鼎鼎的Bjarne StroustrupHerb Sutter

  • 转载请注明原文链接:https://blog.csdn.net/qq_27727147/article/details/116503414

std::move使用不当引起的copy elision相关推荐

  1. C++ Copy Elision

    故事得从 copy/move constructor 说起: The default constructor (12.1), copy constructor and copy assignment ...

  2. c++的复制省略(copy elision)

    学习 A simple C++11 Thread Pool 时,发现函数返回了std::future,而std::future的拷贝构造和拷贝赋值都是delete的,感觉有点怪,查了一下,看到 编译器 ...

  3. Copy Elision

    最近写程序的时候突然意识到了一个(也许大多数人早就意识到的)很常见的问题.我们知道复制一个对象(尤其是复杂的对象/实例)往往需要不小的计算开销(更别提复制一个数组的对象了).但另一方面,复杂对象(群) ...

  4. C++ Copy Elision 1

    故事得从 copy/move constructor 说起: The default constructor (12.1), copy constructor and copy assignment ...

  5. C++ - Copy Elision

    Copy Elision C++11/14/17编译器优化:省略不必要的拷贝 至少包括以下两项内容: 返回值优化(RVO),即通过将返回值所占空间的分配地点从被调用端转移至调用端的手段来避免拷贝操作. ...

  6. 浅谈C++11标准中的复制省略(copy elision,也叫RVO返回值优化)

    严正声明:本文系作者davidhopper原创,未经许可,不得转载. C++11以及之后的C++14.17标准均提出一项编译优化技术:复制省略(copy elision,也称复制消除),另外还有RVO ...

  7. C++17之省略不必要的拷贝Copy Elision

    从C++发展历史看来,c++ 17引入了一个规则,要求在满足一定的条件下避免对象的复制,这在以前是可选的.C++17中一个叫做强制复制省略的技术就是基于这个观点的. 至少包括以下两项内容: 1. 返回 ...

  8. C++中的RVO、NRVO与Copy Elision

    RVO: Return Value Optimization NRVO: Named Return Value Optimization RVO 和 NRVO 自C++98时代就已存在,即当函数按值返 ...

  9. 一道面试题:你了解哪些编译器优化行为?知道Copy elision 、RVO吗?

    C++11以后,g++ 编译器默认开启复制省略(copy elision)选项,可以在以值语义传递对象时避免触发复制.移动构造函数.copy elision 主要发生在两个场景: 函数返回的是值语义时 ...

最新文章

  1. 神经网络 Log-Sum-Exp
  2. 深层神经网络中的前向传播
  3. ANDROID L——Material Design综合应用(Demo)
  4. pytorch 之 torch.bmm()函数
  5. ReviewForJob——深度优先搜索的应用
  6. 六、Analysis of quicksort
  7. spring 多数据源- 原理
  8. appium架构分析
  9. 机器学习方法(一)——梯度下降法
  10. 简单实现DButil工具类
  11. 如何搭建个人视频点播服务器
  12. java 自定义控件_自定义控件的开发
  13. python 高级部分
  14. 您的好友邀请您加入群聊~
  15. 微信小程序-一次性订阅消息推送
  16. 最新支持android的手机型号,android8.0国产手机有哪些 哪些手机支持android 8.0
  17. limit和offset用法
  18. 利用朴素贝叶斯分类算法对搜狐新闻进行分类(python)
  19. Making Youden Plots in R
  20. 精读论文:Multi-Task Learning as Multi-Objective Optimization(附翻译)

热门文章

  1. 文本选择毒战:我的过度阐释
  2. CPU微指令相关概念
  3. Navicat简单使用方法。
  4. 终于可以舒服的看电子书了
  5. Vivado使用技巧(12):设置DCI与内部参考电压
  6. springboot+mybetis实验报告
  7. Adobe国际认证中文官网
  8. C/C++新手入门教程:傻瓜都会的VS2013使用教程,成为程序员的第一步
  9. 基于SSM生产计划排程管理系统
  10. 交换机和路由器到底有什么区别???