File: const-correctness.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 (199 lines) | stat: -rw-r--r-- 6,434 bytes parent folder | download | duplicates (2)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
.. title:: clang-tidy - misc-const-correctness

misc-const-correctness
======================

This check implements detection of local variables which could be declared as
``const`` but are not. Declaring variables as ``const`` is required or recommended by many
coding guidelines, such as:
`ES.25 <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es25-declare-an-object-const-or-constexpr-unless-you-want-to-modify-its-value-later-on>`_
from the C++ Core Guidelines and `AUTOSAR C++14 Rule A7-1-1 (6.7.1 Specifiers)
<https://www.autosar.org/fileadmin/user_upload/standards/adaptive/17-03/AUTOSAR_RS_CPP14Guidelines.pdf>`_.

Please note that this check's analysis is type-based only. Variables that are not modified
but used to create a non-const handle that might escape the scope are not diagnosed
as potential ``const``.

.. code-block:: c++

  // Declare a variable, which is not ``const`` ...
  int i = 42;
  // but use it as read-only. This means that `i` can be declared ``const``.
  int result = i * i;       // Before transformation
  int const result = i * i; // After transformation

The check can analyze values, pointers and references but not (yet) pointees:

.. code-block:: c++

  // Normal values like built-ins or objects.
  int potential_const_int = 42;       // Before transformation
  int const potential_const_int = 42; // After transformation
  int copy_of_value = potential_const_int;

  MyClass could_be_const;       // Before transformation
  MyClass const could_be_const; // After transformation
  could_be_const.const_qualified_method();

  // References can be declared const as well.
  int &reference_value = potential_const_int;       // Before transformation
  int const& reference_value = potential_const_int; // After transformation
  int another_copy = reference_value;

  // The similar semantics of pointers are not (yet) analyzed.
  int *pointer_variable = &potential_const_int; // _NO_ 'const int *pointer_variable' suggestion.
  int last_copy = *pointer_variable;

The automatic code transformation is only applied to variables that are declared in single
declarations. You may want to prepare your code base with
`readability-isolate-declaration <../readability/isolate-declaration.html>`_ first.

Note that there is the check
`cppcoreguidelines-avoid-non-const-global-variables <../cppcoreguidelines/avoid-non-const-global-variables.html>`_
to enforce ``const`` correctness on all globals.

Known Limitations
-----------------

The check does not run on `C` code.

The check will not analyze templated variables or variables that are instantiation dependent.
Different instantiations can result in different ``const`` correctness properties and in general it
is not possible to find all instantiations of a template. The template might be used differently in
an independent translation unit.

Pointees can not be analyzed for constness yet. The following code shows this limitation.

.. code-block:: c++

  // Declare a variable that will not be modified.
  int constant_value = 42;

  // Declare a pointer to that variable, that does not modify either, but misses 'const'.
  // Could be 'const int *pointer_to_constant = &constant_value;'
  int *pointer_to_constant = &constant_value;

  // Usage:
  int result = 520 * 120 * (*pointer_to_constant);

This limitation affects the capability to add ``const`` to methods which is not possible, too.

Options
-------

.. option:: AnalyzeValues (default = true)

  Enable or disable the analysis of ordinary value variables, like ``int i = 42;``

  .. code-block:: c++

    // Warning
    int i = 42;
    // No warning
    int const i = 42;

    // Warning
    int a[] = {42, 42, 42};
    // No warning
    int const a[] = {42, 42, 42};

.. option:: AnalyzeReferences (default = true)

  Enable or disable the analysis of reference variables, like ``int &ref = i;``

  .. code-block:: c++

    int i = 42;
    // Warning
    int& ref = i;
    // No warning
    int const& ref = i;

.. option:: WarnPointersAsValues (default = false)

  This option enables the suggestion for ``const`` of the pointer itself.
  Pointer values have two possibilities to be ``const``, the pointer
  and the value pointing to.

  .. code-block:: c++

    int value = 42;

    // Warning
    const int * pointer_variable = &value;
    // No warning
    const int *const pointer_variable = &value;

.. option:: TransformValues (default = true)

  Provides fixit-hints for value types that automatically add ``const`` if its a single declaration.

  .. code-block:: c++

    // Before
    int value = 42;
    // After
    int const value = 42;

    // Before
    int a[] = {42, 42, 42};
    // After
    int const a[] = {42, 42, 42};

    // Result is modified later in its life-time. No diagnostic and fixit hint will be emitted.
    int result = value * 3;
    result -= 10;

.. option:: TransformReferences (default = true)

  Provides fixit-hints for reference types that automatically add ``const`` if its a single
  declaration.

  .. code-block:: c++

    // This variable could still be a constant. But because there is a non-const reference to
    // it, it can not be transformed (yet).
    int value = 42;
    // The reference 'ref_value' is not modified and can be made 'const int &ref_value = value;'
    // Before
    int &ref_value = value;
    // After
    int const &ref_value = value;

    // Result is modified later in its life-time. No diagnostic and fixit hint will be emitted.
    int result = ref_value * 3;
    result -= 10;

.. option:: TransformPointersAsValues (default = false)

  Provides fixit-hints for pointers if their pointee is not changed. This does not analyze if the
  value-pointed-to is unchanged!

  Requires 'WarnPointersAsValues' to be 'true'.

  .. code-block:: c++

    int value = 42;

    // Before
    const int * pointer_variable = &value;
    // After
    const int *const pointer_variable = &value;

    // Before
    const int * a[] = {&value, &value};
    // After
    const int *const a[] = {&value, &value};

    // Before
    int *ptr_value = &value;
    // After
    int *const ptr_value = &value;

    int result = 100 * (*ptr_value); // Does not modify the pointer itself.
    // This modification of the pointee is still allowed and not diagnosed.
    *ptr_value = 0;

    // The following pointer may not become a 'int *const'.
    int *changing_pointee = &value;
    changing_pointee = &result;