Skip to content

Commit

Permalink
[docs] improve documentation for misc-const-correctness
Browse files Browse the repository at this point in the history
Improve the documentation for 'misc-const-correctness' to:

- include better examples
- improve the english
- fix links to other checks that were broken due to the directory-layout changes
- mention the limitation that the check does not run on `C` code.

Addresses #56749, #56958

Reviewed By: njames93

Differential Revision: https://reviews.llvm.org/D132244
  • Loading branch information
JonasToth committed Aug 29, 2022
1 parent c786968 commit b5b7503
Showing 1 changed file with 80 additions and 32 deletions.
112 changes: 80 additions & 32 deletions clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
Expand Up @@ -4,12 +4,12 @@ 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
``const`` but are not. Declaring variables as ``const`` is required or recommended by many
coding guidelines, such as:
`CppCoreGuidelines ES.25 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es25-declare-an-object-const-or-constexpr-unless-you-want-to-modify-its-value-later-on>`_
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 analysis is type-based only. Variables that are not modified
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``.

Expand All @@ -18,44 +18,50 @@ as potential ``const``.
// 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;
int result = i * i; // Before transformation
int const result = i * i; // After transformation

The check can analyzes values, pointers and references but not (yet) pointees:
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; // 'const int potential_const_int = 42' suggestion.
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; // 'const MyClass could_be_const' suggestion;
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; // 'const int &reference_value' suggestion.
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; // Not 'const int *pointer_variable' suggestion.
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>`_
`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. It might be used differently in an
independent translation unit.
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 is shows this limitation.
Pointees can not be analyzed for constness yet. The following code shows this limitation.

.. code-block:: c++

Expand All @@ -74,44 +80,72 @@ This limitation affects the capability to add ``const`` to methods which is not
Options
-------

.. option:: AnalyzeValues (default = 1)
.. option:: AnalyzeValues (default = true)

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

.. option:: AnalyzeReferences (default = 1)
.. 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;``

.. option:: WarnPointersAsValues (default = 0)
.. 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++

const int value = 42;
const int * const pointer_variable = &value;
int value = 42;

// The following operations are forbidden for `pointer_variable`.
// *pointer_variable = 44;
// pointer_variable = nullptr;
// Warning
const int * pointer_variable = &value;
// No warning
const int *const pointer_variable = &value;
.. option:: TransformValues (default = 1)
.. option:: TransformValues (default = true)

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

.. code-block:: c++

// Emits a hint for 'value' to become 'const int value = 42;'.
// 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 = 1)
.. option:: TransformReferences (default = true)

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

.. code-block:: c++
Expand All @@ -120,31 +154,45 @@ Options
// 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 = 0)
.. 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 1.
Requires 'WarnPointersAsValues' to be 'true'.

.. code-block:: c++

int value = 42;
// Emits a hint that 'ptr_value' may become 'int *const ptr_value = &value' because its pointee
// is not changed.

// 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);
// This modification of the pointee is still allowed and not analyzed/diagnosed.
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;

0 comments on commit b5b7503

Please sign in to comment.