Cyclomatic complexity exceeds threshold

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

Description

Polyspace® calculates the cyclomatic complexity of a function by adding one to the number of decision points. A decision point is a statement that causes your program to branch into two paths. This defect is raised when the cyclomatic complexity of a function is greater than the defined cyclomatic complexity threshold. For details about how Polyspace calculates cyclomatic complexity, see .

Polyspace uses the default threshold 10 unless you specify a threshold. To specify a selection file where you can set the threshold, use Set checkers by file (-checkers-selection-file) (Polyspace Bug Finder Server). Also see Reduce Software Complexity by Using Polyspace Checkers (Polyspace Bug Finder Server).

When you import comments from previous analyses by using , Polyspace copies any review information on the code metric in the previous result to this checker in the current result. If the current result contains the same code metric, the review information is copied to the code metric as well.

Risk

Violation of this checker might indicate that the function contains too many branches. Such functions are difficult to test and might contain unknown defects or bugs that are difficult to debug.

Fix

To fix this check:

  • Refactor your code to avoid nested control structures.

  • Refactor your code to split a complex function into multiple functions that are simpler and easy to test.

  • Modify the checker selection XML file to raise the cyclomatic complexity threshold.

A best practice is to check the complexity of a module early in development to avoid costly post-development refactoring.

Examples

expand all

int afunc (int x);
int foo(int x,int y) //Noncompliant
{
	int flag;
	if (x <= 0){
		if (x > 10 ) { return 0; }
	}
	if (x<-240) {
		if (x < -2565) { 
			return (x < -253 ? 0: afunc (x <22566 ? 1: afunc(x < -25103 ? 0: 6))); 
		}
	}
	for (int i = 0; i< 10; i++)
	{
		while (x < y ) flag = 1;
		do {++x;} while (i<7);
		flag = 0;
	}
	return flag;
}

In this example, the function foo has too many decision points, resulting in a cyclomatic complexity of 11, which is greater than the default threshold of 10. Because the function has many decision points, testing the function is difficult and testing might fail to cover all execution paths. Polyspace flags the function as noncompliant.

Correction — Refactor the Function

One possible correction is to split the function into two functions.

int afunc (int x);
int foo2(int x,int y)//Compliant 
{
	
	if (x <= 0){
		if (x > 10 ) { return 0; }
	}
	if (x<-240) {
		if (x < -2565) { 
			return (x < -253 ? 0: afunc (x <22566 ? 1: afunc(x < -25103 ? 0: 6))); 
		}
	}
}

int bar(int x,int y){//Complaint
	int flag;
	for (int i = 0; i< 10; i++)
	{
		while (x < y ) flag = 1;
		do {++x;} while (i<7);
		flag = 0;
	}
	return flag;
}

The functions foo2 and bar have acceptable cyclomatic complexity and are easier to test compared to foo.

Check Information

Group: Software Complexity
Language: C | C++
Acronym: SC17
Default Threshold: 10
Introduced in R2021a