readability-function-cognitive-complexity¶
检查函数的认知复杂度指标。
该指标的实现遵循 SonarSource 的认知复杂度 规范版本 1.2 (2017 年 4 月 19 日)。
选项¶
- Threshold¶
标记认知复杂度超过此值的函数。默认值为 25。
- DescribeBasicIncrements¶
如果设置为 true,则对于每个超过复杂度阈值的函数,该检查将针对每个导致该复杂度的代码段 (循环、if 语句等) 发布额外的诊断信息。另请参阅下面的示例。默认值为 true。
- IgnoreMacros¶
如果设置为 true,该检查将忽略宏内的代码。注意,任何宏参数也将被忽略,即使它们应计入复杂度。由于这将来可能会发生变化,因此此选项不能保证与将来版本兼容。默认值为 false。
构建块¶
认知复杂度指标有三个基本构建块
增量¶
以下结构会增加函数的认知复杂度指标 (增加 1)
条件运算符
if()
else if()
else
cond ? true : false
switch()
循环
for()
C++11 基于范围的
for()
while()
do while()
catch ()
goto LABEL
,goto *(&&LABEL))
,二元逻辑运算符序列
boolean1 || boolean2
boolean1 && boolean2
嵌套级别¶
虽然嵌套级别本身不会改变函数的认知复杂度指标,但它会被跟踪,并被下一个第三个构建块使用。以下结构会增加嵌套级别 (增加 1)
条件运算符
if()
else if()
else
cond ? true : false
switch()
循环
for()
C++11 基于范围的
for()
while()
do while()
catch ()
嵌套函数
C++11 Lambda
嵌套
class
嵌套
struct
GNU 语句表达式
Apple 块声明
嵌套增量¶
这是前面的基本构建块 嵌套级别 起作用的地方。以下结构会将函数的认知复杂度指标增加当前 嵌套级别
条件运算符
if()
cond ? true : false
switch()
循环
for()
C++11 基于范围的
for()
while()
do while()
catch ()
示例¶
最简单的例子。此函数的认知复杂度为 0。
void function0() {}
稍微好一点的例子。此函数的认知复杂度为 1。
int function1(bool var) {
if(var) // +1, nesting level +1
return 42;
return 0;
}
完整示例。此函数的认知复杂度为 3。
int function3(bool var1, bool var2) {
if(var1) { // +1, nesting level +1
if(var2) // +2 (1 + current nesting level of 1), nesting level +1
return 42;
}
return 0;
}
在最后一个示例中,如果选项 Threshold 设置为 2 或更小,则该检查将标记 function3。如果选项 DescribeBasicIncrements 设置为 true,它还将标记两个 if 语句,以及它们对函数复杂度和当前嵌套级别的增加量。
局限性¶
- 该指标的实现有以下两个显著例外
预处理器条件 (
#ifdef
,#if
,#elif
,#else
,#endif
) 未计入。递归循环中的每个方法 未计入。它无法完全实现,因为需要进行跨翻译单元分析,而 clang-tidy 目前尚不支持此功能。