1.. title:: clang-tidy - performance-no-automatic-move 2 3performance-no-automatic-move 4============================= 5 6Finds local variables that cannot be automatically moved due to constness. 7 8Under 9`certain conditions <https://en.cppreference.com/w/cpp/language/return#automatic_move_from_local_variables_and_parameters>`_, 10local values are automatically moved out when returning from a function. A 11common mistake is to declare local ``lvalue`` variables ``const``, which 12prevents the move. 13 14Example `[1] <https://godbolt.org/z/x7SYYA>`_: 15 16.. code-block:: c++ 17 18 StatusOr<std::vector<int>> Cool() { 19 std::vector<int> obj = ...; 20 return obj; // calls StatusOr::StatusOr(std::vector<int>&&) 21 } 22 23 StatusOr<std::vector<int>> NotCool() { 24 const std::vector<int> obj = ...; 25 return obj; // calls `StatusOr::StatusOr(const std::vector<int>&)` 26 } 27 28The former version (``Cool``) should be preferred over the latter (``Uncool``) 29as it will avoid allocations and potentially large memory copies. 30 31Semantics 32--------- 33 34In the example above, ``StatusOr::StatusOr(T&&)`` have the same semantics as 35long as the copy and move constructors for ``T`` have the same semantics. Note 36that there is no guarantee that ``S::S(T&&)`` and ``S::S(const T&)`` have the 37same semantics for any single ``S``, so we're not providing automated fixes for 38this check, and judgement should be exerted when making the suggested changes. 39 40-Wreturn-std-move 41----------------- 42 43Another case where the move cannot happen is the following: 44 45.. code-block:: c++ 46 47 StatusOr<std::vector<int>> Uncool() { 48 std::vector<int>&& obj = ...; 49 return obj; // calls `StatusOr::StatusOr(const std::vector<int>&)` 50 } 51 52In that case the fix is more consensual: just `return std::move(obj)`. 53This is handled by the `-Wreturn-std-move` warning. 54