File: rvalue-reference-param-not-moved.rst

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (85 lines) | stat: -rw-r--r-- 2,689 bytes parent folder | download | duplicates (8)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.. title:: clang-tidy - cppcoreguidelines-rvalue-reference-param-not-moved

cppcoreguidelines-rvalue-reference-param-not-moved
==================================================

Warns when an rvalue reference function parameter is never moved within
the function body.

Rvalue reference parameters indicate a parameter that should be moved with
``std::move`` from within the function body. Any such parameter that is
never moved is confusing and potentially indicative of a buggy program.

Example:

.. code-block:: c++

  void logic(std::string&& Input) {
    std::string Copy(Input); // Oops - forgot to std::move
  }

Note that parameters that are unused and marked as such will not be diagnosed.

Example:

.. code-block:: c++

  void conditional_use([[maybe_unused]] std::string&& Input) {
    // No diagnostic here since Input is unused and marked as such
  }

Options
-------

.. option:: AllowPartialMove

   If set to `true`, the check accepts ``std::move`` calls containing any
   subexpression containing the parameter. CppCoreGuideline F.18 officially
   mandates that the parameter itself must be moved. Default is `false`.

  .. code-block:: c++

    // 'p' is flagged by this check if and only if AllowPartialMove is false
    void move_members_of(pair<Obj, Obj>&& p) {
      pair<Obj, Obj> other;
      other.first = std::move(p.first);
      other.second = std::move(p.second);
    }

    // 'p' is never flagged by this check
    void move_whole_pair(pair<Obj, Obj>&& p) {
      pair<Obj, Obj> other = std::move(p);
    }

.. option:: IgnoreUnnamedParams

   If set to `true`, the check ignores unnamed rvalue reference parameters.
   Default is `false`.

.. option:: IgnoreNonDeducedTemplateTypes

   If set to `true`, the check ignores non-deduced template type rvalue
   reference parameters. Default is `false`.

  .. code-block:: c++

    template <class T>
    struct SomeClass {
      // Below, 'T' is not deduced and 'T&&' is an rvalue reference type.
      // This will be flagged if and only if IgnoreNonDeducedTemplateTypes is
      // false. One suggested fix would be to specialize the class for 'T' and
      // 'T&' separately (e.g., see std::future), or allow only one of 'T' or
      // 'T&' instantiations of SomeClass (e.g., see std::optional).
      SomeClass(T&& t) { }
    };

    // Never flagged, since 'T' is a forwarding reference in a deduced context
    template <class T>
    void forwarding_ref(T&& t) {
      T other = std::forward<T>(t);
    }

This check implements `F.18
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f18-for-will-move-from-parameters-pass-by-x-and-stdmove-the-parameter>`_
from the C++ Core Guidelines.