misc-const-correctness

此检查实现检测可以声明为 const 但未声明为 const 的局部变量。许多编码规范要求或推荐将变量声明为 const,例如:C++ 核心准则中的 ES.25

请注意,此检查的分析仅基于类型。未修改但用于创建可能超出范围的非 const 句柄的变量不会被诊断为潜在的 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

此检查可以分析值、指针和引用,但不能(尚未)分析指向的值。

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

自动代码转换仅应用于在单个声明中声明的变量。您可能希望先使用 readability-isolate-declaration 准备您的代码库。

请注意,存在检查 cppcoreguidelines-avoid-non-const-global-variables 以在所有全局变量上强制执行 const 正确性。

已知限制

此检查不会在 C 代码上运行。

此检查不会分析模板变量或与实例化相关的变量。不同的实例化会导致不同的 const 正确性属性,通常无法找到模板的所有实例化。该模板可能在独立的翻译单元中以不同的方式使用。

指向的值目前无法分析其 const 性。以下代码显示了此限制。

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

此限制会影响添加 const 到方法的能力,这也是不可能的。

选项

AnalyzeValues (默认 = true)

启用或禁用对普通值变量的分析,例如 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 (默认 = true)

启用或禁用对引用变量的分析,例如 int &ref = i;

int i = 42;
// Warning
int& ref = i;
// No warning
int const& ref = i;
WarnPointersAsValues (默认 = false)

此选项启用对指针本身的 const 建议。指针值有两方面可能成为 const,即指针本身和指向的值。

int value = 42;

// Warning
const int * pointer_variable = &value;
// No warning
const int *const pointer_variable = &value;
TransformValues (默认 = true)

为值类型提供修复提示,如果它是一个单个声明,则会自动添加 const

// 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 (默认 = true)

为引用类型提供修复提示,如果它是一个单个声明,则会自动添加 const

// 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 (默认 = false)

如果指针的指向值未更改,则为指针提供修复提示。这不会分析指向的值是否保持不变!

需要将 ‘WarnPointersAsValues’ 设置为 ‘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;