web-dev-qa-db-ja.com

C ++の偽のコピー操作を見つける方法は?

最近、私は次のことをしました

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

data get_vector(int n)
{
  std::vector<int> V(n,0);
  return {V};
}

このコードの問題は、構造体が作成されたときにコピーが発生し、代わりにreturn {std :: move(V)}と書くことです。

このような偽のコピー操作を検出するリンターまたはコードアナライザーはありますか? cppcheck、cpplint、clang-tidyのいずれも実行できません。

編集:私の質問を明確にするためのいくつかのポイント:

  1. compiler Explorerを使用したためにコピー操作が発生し、memcpyへの呼び出しが表示されることがわかっています。
  2. コピー操作が発生したことは、標準のyesを確認することで確認できました。しかし、私の最初の間違った考えは、コンパイラーがこのコピーを最適化するというものでした。私は間違っていた。
  3. Clangとgccの両方がmemcpyを生成するコードを生成するため、これは(おそらく)コンパイラーの問題ではありません。
  4. Memcpyは安いかもしれませんが、メモリをコピーしてオリジナルを削除する方がstd :: moveでポインタを渡すよりも安い状況は想像できません。
  5. std :: moveの追加は、基本的な操作です。コードアナライザーがこの修正を提案できると思います。

コンパイラエクスプローラを使用してmemcpyへの呼び出しを表示したため、コピー操作が発生したことがわかります。

完全なアプリケーションをコンパイラエクスプローラーに入れましたか?最適化を有効にしましたか?そうでない場合は、コンパイラー・エクスプローラーに表示されたものが、アプリケーションで何が起こっているのかではない可能性があります。

投稿したコードの1つの問題は、最初に_std::vector_を作成してから、それをdataのインスタンスにコピーすることです。ベクトルでinitializedataすることをお勧めします。

_data get_vector(int n)
{
  return {std::vector<int> V(n,0)};
}
_

また、コンパイラーエクスプローラーにdataget_vector()の定義を与えるだけで、それ以外の場合は、悪いことを期待する必要があります。 usesget_vector()を使用するソースコードを実際に提供する場合は、そのソースコードに対して生成されるアセンブリを確認します。上記の変更と実際の使用法およびコンパイラーの最適化によってコンパイラーが生成できるものについては、 この例 を参照してください。

1
G. Sliepen