readability-function-cognitive-complexity

Checks function Cognitive Complexity metric.

The metric is implemented as per the COGNITIVE COMPLEXITY by SonarSource specification version 1.2 (19 April 2017).

Options

Threshold

Flag functions with Cognitive Complexity exceeding this number. The default is 25.

Building blocks

There are three basic building blocks of a Cognitive Complexity metric:

Increment

The following structures increase the function’s Cognitive Complexity metric (by 1):

  • Conditional operators:

    • if()
    • else if()
    • else
    • cond ? true : false
  • switch()

  • Loops:

    • for()
    • C++11 range-based for()
    • while()
    • do while()
  • catch ()

  • goto LABEL, goto *(&&LABEL)),

  • sequences of binary logical operators:

    • boolean1 || boolean2
    • boolean1 && boolean2

Nesting level

While by itself the nesting level not change the function’s Cognitive Complexity metric, it is tracked, and is used by the next, third building block. The following structures increase the nesting level (by 1):

  • Conditional operators:

    • if()
    • else if()
    • else
    • cond ? true : false
  • switch()

  • Loops:

    • for()
    • C++11 range-based for()
    • while()
    • do while()
  • catch ()

  • Nested functions:

    • C++11 Lambda
    • Nested class
    • Nested struct
  • GNU statement expression

  • Apple Block Declaration

Nesting increment

This is where the previous basic building block, Nesting level, matters. The following structures increase the function’s Cognitive Complexity metric by the current Nesting level:

  • Conditional operators:

    • if()
    • cond ? true : false
  • switch()

  • Loops:

    • for()
    • C++11 range-based for()
    • while()
    • do while()
  • catch ()

Examples

The simplest case. This function has Cognitive Complexity of 0.

void function0() {}

Slightly better example. This function has Cognitive Complexity of 1.

int function1(bool var) {
  if(var) // +1, nesting level +1
    return 42;
  return 0;
}

Full example. This function has Cognitive Complexity of 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;
}

Limitations

The metric is implemented with two notable exceptions:
  • preprocessor conditionals (#ifdef, #if, #elif, #else, #endif) are not accounted for.
  • each method in a recursion cycle is not accounted for. It can’t be fully implemented, because cross-translational-unit analysis would be needed, which is currently not possible in clang-tidy.