# Extra Clang Tools 22.1.2 documentation

## clang-tidy - performance-no-automatic-move

# performance-no-automatic-move

Finds local variables that cannot be automatically moved due to constness.

Under certain conditions, local values are automatically moved out when returning from a function. A common mistake is to declare local `lvalue` variables `const`, which prevents the move.

Example [1]:

    StatusOr<std::vector<int>> Cool() {
      std::vector<int> obj = ...;
      return obj;  // calls StatusOr::StatusOr(std::vector<int>&&)
    }

    StatusOr<std::vector<int>> NotCool() {
      const std::vector<int> obj = ...;
      return obj;  // calls `StatusOr::StatusOr(const std::vector<int>&)`
    }

The former version (`Cool`) should be preferred over the latter (`NotCool`) as it will avoid allocations and potentially large memory copies.

## Semantics

In the example above, `StatusOr::StatusOr(T&&)` have the same semantics as long as the copy and move constructors for `T` have the same semantics. Note that there is no guarantee that `S::S(T&&)` and `S::S(const T&)` have the same semantics for any single `S`, so we’re not providing automated fixes for this check, and judgement should be exerted when making the suggested changes.

## -Wreturn-std-move

Another case where the move cannot happen is the following:

    StatusOr<std::vector<int>> Uncool() {
      std::vector<int>&& obj = ...;
      return obj;  // calls `StatusOr::StatusOr(const std::vector<int>&)`
    }

In that case the fix is more consensual: just return std::move(obj). This is handled by the -Wreturn-std-move warning.