File: no-automatic-move.rst

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (53 lines) | stat: -rw-r--r-- 1,812 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
.. title:: clang-tidy - performance-no-automatic-move

performance-no-automatic-move
=============================

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

Under
`certain conditions <https://en.cppreference.com/w/cpp/language/return#automatic_move_from_local_variables_and_parameters>`_,
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] <https://godbolt.org/z/x7SYYA>`_:

.. code-block:: c++

  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:

.. code-block:: c++

  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.