Contenu principal

SC22 Function cognitive complexity exceeds threshold

R2026b

The function cognitive complexity of a function is greater than the defined threshold

Since R2026b

Description

Function cognitive complexity (FCC) estimates how difficult a function is to read and reason about. Polyspace® scans the code inside a function body and looks for control flow interruptions and nested structures.

void func() {
  // Only statements inside this function contribute to the FCC for func
}
      
The function cognitive complexity has two components:

  • Linear score — A count of control flow interruptions in the function. Polyspace increments the linear score by 1 for each of these control flow interruptions:

    • else

    • continue

    • break — Only when not used as a case statement terminator

    • goto statement

    • goto label (target)

    • Direct recursive calls

    • First logical operator in a boolean expression (&& or ||)

    • Each change of logical operator type in a boolean expression (for example, switching from && to ||)

    else if is treated as a single construct, not as nested else containing if, to avoid double counting. For example, in this code, each control flow interruption increments the linear score by 1:

    
    void g(bool a, bool b, bool c) {
      if (a && b || c) {}  // linear score imrement: +1 for first operator (&&), +1 for operator change (||)
      else if (b) {}        // linear score imrement: +1 for else
      else {                // linear score imrement: +1 for else
        if (c) goto end;    // linear score imrement: +1 for goto
      }
      end: return;          // linear score imrement: +1 for goto label
    }
    // Linear score: 6
    

  • Nesting score — A measure of control flow structure nesting depth. Polyspace increments the nesting score for each nested construct by 1 plus its current nesting depth. The following constructs contribute to nesting:

    • if statements (excluding else if)

    • Ternary operator ?:

    • switch statements

    • for loops

    • while loops

    • do loops

    • catch clauses

    For example, in this code, the nesting score increment increases with deeper nesting levels:

    
    void h(bool a, int n) {
      if (a) {                  // nesting score increment: (0+1) = 1
        for (int i=0;i<n;++i) { // nesting score increment: (1+1) = 2
          int x = a ? 1 : 2;    // nesting score increment: (2+1) = 3
        }
      }
    }
    
    Polyspace considers lambdas to increase the nesting depth of child elements by one.

The total cognitive complexity of a function is the sum of these two scores:

FCC = Linear Score + Nesting Score

Polyspace reports a violation when the total cognitive complexity exceeds the specified threshold. Polyspace uses a default threshold of 15 unless you specify a different threshold. To specify an activation XML file where you can set the threshold, use the option Checkers activation file (-checkers-activation-file).

Risk

Exceeding the function cognitive complexity threshold indicates that the function contains many divergent control flow paths and a high degree of nesting, making the function difficult to read and understand. These kinds of functions are difficult to maintain and test because of their complex structure. Functions with high cognitive complexity are also more difficult to parse using AI-based tools, which can obstruct workflows that rely on automated code analysis or generation.

Fix

To fix this violation:

  • Reduce nesting by using early returns or guard clauses.

  • Extract deeply nested logic into separate helper functions.

  • Simplify boolean expressions by breaking them into named variables.

  • Replace complex conditional chains with simpler control flow structures.

Examples

expand all

In this example, the function sumOfPrimes() uses nested loops and conditional logic that result in a cognitive complexity of 7. If you set the threshold for this guideline at 5, then Polyspace reports a violation.

int sumOfPrimes(int max) {  //Noncompliant
    int total = 0;
    OUT: for (int i = 1; i <= max; ++i) {   // nesting: +(0+1)
        for (int j = 2; j < i; ++j) {        // nesting: +(1+1)
            if (i % j == 0) {                 // nesting: +(2+1)
                goto OUT;                     // linear: +1
            }
        }
        total += i;
    }
    return total;
}
// Total: 7 (nesting score = 6, linear score = 1)  

To set the threshold for this guideline to 5, save this XML code in an XML file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- DO NOT EDIT THIS FILE: Some changes can lead to a crash of Polyspace products -->
<polyspace_checkers_selection revision="2.0">
  <standard name="Bug Finder Findings" state="off"></standard>
  <standard name="CUSTOM RULES" state="off"></standard>
  <standard name="Guidelines">
    <section name="Software Complexity">
      <check id="SC22" state="on">
        <threshold>5</threshold>
      </check>
    </section>
  </standard>
</polyspace_checkers_selection>
Run the Polyspace Bug Finder™ analysis by using this XML file as an input to the option Checkers activation file (-checkers-activation-file).

Correction — Reduce Nesting and Simplify Logic

One possible correction is to reduce the nesting depth by using an early return and extracting the inner logic into a helper function. In this refactored code, the function sumOfPrimes() has a cognitive complexity of 3, which is below the specified threshold 5.

#include <stdbool.h>

bool isPrime(int n) {
    for (int j = 2; j < n; ++j) {  // nesting: +(0+1)
        if (n % j == 0) {           // nesting: +(1+1)
            return false;
        }
    }
    return true;
}
// isPrime total: 3 (nesting score = 3, linear score = 0)

int sumOfPrimes(int max) {
    int total = 0;
    for (int i = 2; i <= max; ++i) {  // nesting: +(0+1)
        if (isPrime(i)) {               // nesting: +(1+1)
            total += i;
        }
    }
    return total;
}
// sumOfPrimes total: 3 (nesting score = 3, linear score = 0)

Check Information

Group: Software Complexity
Language: C | C++
Acronym: SC22
Default Threshold: 15

Version History

Introduced in R2026b