Есть ли предупреждение компиляции об этом использовании std :: move? - PullRequest
5 голосов
/ 24 февраля 2020

Следующая программа показывает два проблемных c (но технически обоснованных) использования std::move(). Можно ли получить предупреждение об этом с помощью LLVM? Я заметил, что есть диагностика c для некоторых других контекстов, где std::move является избыточным.

Я скомпилировал это с bcc32 c версии 5.0.2 (на основе LLVM 5.0.2) и получил нет предупреждения.

#include <vector>

int main() {
    const std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {3, 4, 5};

    std::vector<int> c = std::move(a); // std::move from const

    std::vector<int> d = std::move(b);

    std::vector<int> e = b; // used after std::move
}

Ответы [ 2 ]

4 голосов
/ 24 февраля 2020

clang-tidy's bugprone-use-after-move контролер поддерживает этот тип диагностики c:

bugprone-use-after-move

Предупреждения если объект используется после его перемещения, например:

std::string str = "Hello, world!\n";
std::vector<std::string> messages;
messages.emplace_back(std::move(str));
std::cout << str;

Последняя строка вызовет предупреждение о том, что str используется после его перемещения.

[... ]

Использование

Любое вхождение перемещенной переменной, которая не является повторной инициализацией (см. Ниже), считается использованием.

[. ..]

Если после перемещения происходит многократное использование, помечается только первое из них.

3 голосов
/ 24 февраля 2020

clang-tidy имеет проверку performance-move-const-arg, которая предупреждает:

  1. если std :: move () вызывается с постоянным аргументом,
  2. если std :: move () вызывается с аргументом тривиально копируемого типа,
  3. , если результат std :: move () передается как ссылочный аргумент const.

Во всех трех случаях проверка предложит исправление, удаляющее std :: move ().

со следующими примерами:

const string s;
return std::move(s);  // Warning: std::move of the const variable has no effect

int x;
return std::move(x);  // Warning: std::move of the variable of a trivially-copyable type has no effect

void f(const string &s);
string s;
f(std::move(s));      // Warning: passing result of std::move as a const reference argument; no move will actually happen
...