clang-tidy - misc-const-correctness — Extra Clang Tools 16.0.6 documentation

# Extra Clang Tools 16.0.6 documentation

## 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: CppCoreGuidelines ES.25 and AUTOSAR C++14 Rule A7-1-1 (6.7.1 Specifiers).

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`.

    // 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:

    // 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 first.

Note that there is the check cppcoreguidelines-avoid-non-const-global-variables 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.

    // 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

AnalyzeValues (default = true)

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

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

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

AnalyzeReferences (default = true)

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

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

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.

      int value = 42;

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

TransformValues (default = true)

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

      // 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;

TransformReferences (default = true)

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

      // 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;

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’.

      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;