如何找到 C++ 虚假复制操作?

Mat*_*ric 12 c++ code-analysis static-code-analysis cppcheck

最近,我有以下情况

struct data {
  std::vector<int> V;
};

data get_vector(int n)
{
  std::vector<int> V(n,0);
  return {V};
}
Run Code Online (Sandbox Code Playgroud)

这段代码的问题在于,在创建结构体时会发生一个副本,而解决方案是编写return {std::move(V)}

是否有可以检测这种虚假复制操作的 linter 或代码分析器?cppcheck、cpplint 和 clang-tidy 都做不到。

编辑:几点让我的问题更清楚:

  1. 我知道发生复制操作是因为我使用了编译器资源管理器,它显示了对memcpy的调用。
  2. 我可以通过查看标准 yes 来确定发生了复制操作。但我最初的错误想法是编译器会优化掉这个副本。我错了。
  3. 这(很可能)不是编译器问题,因为 clang 和 gcc 都产生产生memcpy 的代码。
  4. memcpy 可能很便宜,但我无法想象复制内存和删除原始内存比通过std::move传递指针便宜的情况。
  5. 添加std::move是一个基本操作。我想代码分析器将能够建议此更正。

G. *_*pen 1

我知道发生了复制操作,因为我使用了编译器资源管理器,它显示了对 memcpy 的调用。

您是否将完整的应用程序放入编译器资源管理器中,并启用了优化?如果不是,那么您在编译器资源管理器中看到的内容可能是也可能不是您的应用程序所发生的情况。

您发布的代码的一个问题是您首先创建一个std::vector,然后将其复制到 的实例中data。最好用向量初始化: data

data get_vector(int n)
{
  return {std::vector<int> V(n,0)};
}
Run Code Online (Sandbox Code Playgroud)

data另外,如果您只向编译器资源管理器提供和的定义get_vector(),而没有其他任何内容,那么它必须期待更糟糕的情况。如果您实际上给它一些使用的 get_vector()源代码,那么看看为该源代码生成了什么程序集。请参阅此示例,了解上述修改加上实际使用加上编译器优化可能会导致编译器产生什么结果。