Main Content

Depth of call nesting exceeds threshold

The nesting depth of control structures in a function is greater than the defined nesting depth threshold of a function

Since R2021a

Description

This defect is raised when the nesting depth of control structures in a function, such as for, if-else, switch, or while, exceeds the defined nesting depth threshold. For details about how Polyspace® calculates the nesting depth, see Number of Call Levels.

Polyspace uses the default threshold 4 unless you specify a threshold. To specify a selection file where you can set the threshold, use the option Set checkers by file (-checkers-selection-file) or Checkers activation file (-checkers-activation-file).

When you import comments from previous analyses by using polyspace-comments-import, Polyspace copies any review information on the code metric Number of Call Levels 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 is difficult to read and understand.

  • The function performs too many tasks at once.

  • The function contains unexpected or unplanned development.

These factors make the module difficult to maintain and debug.

Fix

To fix this check, either refactor your code or change the checker threshold. When refactoring your code:

  • Design the function to perform a single task.

  • Delegate unrelated tasks to other functions.

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

Examples

expand all

int foo(int i, int j, int k) //Noncompliant
{
	int m = 0;
	for(i = 0; i < 10; i++)
	{
		for(j = 0; j < 10; j++)
		{
			for(k = 0; k < 10; k++)
			{
				if(i < 2 && j > 5 && k < 7)
					m += 1;
				else
				{
					if(i > 5 && j < 8 && k > 8) {
						m += -1 ;
					} else
						if(i == j) {
							m += 2;
						} else
							if(j == k) {
								m += 3;
							} else {
								m += 1;
							}
				}
			}
		}
	}
	return m;
}

In this example, the depth of call nesting is 7. Polyspace starts counting the depth of nesting from 0 and increments the depth for each control structure. Each else block in an if-else block is considered an additional layer of nesting. The high depth of nesting exceeds the predefined threshold of 4, and makes the function difficult to read, update, or maintain.

Correction — Refactor the Function

One possible correction is to delegate different tasks to different functions. For instance, delegate the conditional actions in foo() to another function getDelta(). The depth of call nesting of these functions are 3 and 4, respectively. The depth of call nesting of these functions do not exceed the threshold value of 4.

int getDelta(int i, int j, int k) { //Compliant
	int delta = 0;
	if(i < 2 && j > 5 && k < 7)
	{
		delta = 1;
	}
	else {
		if(i > 5 && j < 8 && k > 8) {
			delta = -1 ;
		} else
			if(i == j) {
				delta = 2;
			} else
				if(j == k) {
					delta = 3;
				} else {
					delta = 1;
				}
	}

}
int foo(int i, int j, int k) //Compliant
{
	int m = 0;
	for(i = 0; i < 10; i++)
	{
		for(j = 0; j < 10; j++)
		{
			for(k = 0; k < 10; k++)
			{
				m += getDelta(i, j, k);
			}
		}
	}
	return m;
}

Check Information

Group: Software Complexity
Language: C | C++
Acronym: SC14
Default Threshold: 4

Version History

Introduced in R2021a