Reduce Software Complexity by Using Polyspace Checkers
Software complexity refers to various quantifiable metrics of a software module or source files, such as number of lines, number of paths, number of functions, or the complexity of the function call tree. The Polyspace® software complexity checkers are raised when these metrics exceeds a threshold. High software complexity might indicate that your code is difficult to read, understand, and debug. It is more efficient to maintain the acceptable level of software complexity during development instead of refactoring complex projects later on. Use the software complexity checkers to detect complex modules early in the development cycle to reduce later refactoring efforts.
You can also calculate the absolute values of code complexity metrics for all files and functions. See Compute Code Complexity Metrics Using Polyspace.
Check Code Complexity using Hersteller Initiative Software Standard
The Guidelines coding rules reports violations if a code complexity metric of your code exceeds a specified threshold. By default, Polyspace Bug Finder™ sets the thresholds to those specified by the Hersteller Initiative Software (HIS) Code Complexity standard. To check if your code complexity metrics remain within the limits suggested by HIS standard, activate the Guidelines coding rules using the Checkers selection window.
Open the Checkers selection window. You open this window differently depending on your Polyspace product. See:
Configure Checkers for Polyspace as You Code in Eclipse (Polyspace Access)
Configure Checkers for Polyspace as You Code in Visual Studio (Polyspace Access)
Configure Checkers for Polyspace as You Code in Visual Studio Code (Polyspace Access)
Configure Checkers for Polyspace as You Code at the Command Line (Polyspace Access)
Navigate to Guidelines > Software Complexity and enable the rules that correspond to the HIS standard. See HIS Code Complexity Metrics.
You do not need to change the default threshold for the Guidelines check when you check against the HIS standard.
Check Code Complexity using Custom Threshold
You can define a set of custom code complexity threshold for your code. First,
determine an appropriate set of thresholds depending on the best practice for your use
case. For instance, when analyzing new projects or newly developed code, you might want
to reduce the use of GOTO
statements by setting the threshold of
Number of goto
statements exceeds threshold
to zero. When analyzing modules
containing legacy libraries, you might want to set the threshold to a higher
number.
Once you have defined a set of threshold, you can specify these thresholds in the Checkers selection window.
Open the Checkers selection window. You open this window differently depending on your Polyspace product.
Navigate to Guidelines > Software Complexity and enable the rules you want.
On the Threshold field, specify the custom threshold.
Identify and Reduce Software Complexity
Identify Software Complexity by Running Bug Finder Analysis
To identify software complexity, configure the thresholds of the checkers. For instance, set the thresholds of the checkers listed in this table.
Checker | Threshold |
---|---|
Comment density below threshold | 20 |
Call tree complexity exceeds
threshold | 10 |
Number of call occurrences exceeds
threshold | 10 |
Language scope exceeds threshold | 400 |
The thresholds indicate the acceptable level of software complexity. To identify issues in your code that might lead to a higher level of complexity, after configuring the software complexity checkers, run a Polyspace Bug Finder analysis. Consider this code:
long long power(double x, int n){ long long BN = 1; for(int i = 0; i<n;++i){ BN*=x; } return BN; } double AppxIndex(double m, double f){//Noncompliant double U = (power(m,2) - 1)/(power(m,2)+2); double V = (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3); return (1+2*f*power(U,2)*(1+power(m,2)*U*V+ power(m,3) /power(m,3)*(U-V)))/( (1-2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/power(m,3)*(U-V)))); }
AppxIndex
appears complex. It is not obvious how you
might reduce the complexity. The software complexity checkers help you identify the
sources of complexity.After the Bug Finder analysis, the configured checkers are raised:
Comment density below threshold
: The functions in the code contain no explanatory comments.Call tree complexity exceeds threshold
andNumber of call occurrences exceeds threshold
: There are too many function calls compared to the number of function definitions. These checks indicate that you can package some of the expressions into separate functions.Language scope exceeds threshold
: The same operand is repeated several times. You can reduce some of the repetition. For instance, the functionpower
is called with the same arguments several times.
These checks indicate that the function AppxIndex
might make the code difficult to read, understand, and debug. To reduce the
complexity of the code, address the raised checks.
Reduce Software Complexity
Reduce the complexity of your code by addressing the identified issues. In this
case, the root cause of the raised checks is that the function
AppxIndex
performs several tasks instead of performing one
single task. For instance, the function first calculates U
, then
it calculates V
, and finally it evaluates a lengthy expression
containing both U
and V
. To address these
issues, refactor the function AppxIndex
so that each task is
delegated to a separate function. You might break down the lengthy expression into
smaller parts. For
instance:
// This code calculates effective index of materials as described in // the formula in 10.1364... // power(x,n) returns the nth power of x (x^n) // n is an integer // x is a double // return type is long long long long power(double x, int n){//Compliant long long BN = 1; for(int i = 0; i<n;++i){ BN*=x; } return BN; } // CalculateU(m) calculates the first intermediate variable // required to calculate polarization // m is the relative refractive index // return type is double; double CalculateU(double m){//Compliant return (power(m,2) - 1)/(power(m,2)+2); } // CalculateV(m) calculates the second intermediate variable // required to calculate polarization // m is the relative refractive index // return type is double; double CalculateV(double m){//Compliant return (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3); } // CalculateMid(m,f) calculates the large term present // in both numerator and denominator // of the effective index calculation // m is the relative refractive index // f is the fillfactor // return type is double; double CalculateMid(double m, double f){//Compliant double U = CalculateU(m); double V = CalculateU(m); return 2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/power(m,3)*(U-V)); } //AppxIndex(m,f) calculates the approximate effective index // m is the relative refractive index // f is the fillfactor //return type is double double AppxIndex(double m, double f){//Compliant return (1+CalculateMid(m,f))/( (1-CalculateMid(m,f))); }
Document the code with sufficient comments.
Break down the large complex task performed by
AppxIndex
into smaller and simpler tasks, which are then delegated to individual functions such asCalculateU
,CalculateV
andCalculateMid
. The functionpower
is now called less frequently. If you later implement a different function to calculate a power and want to use the new function instead of the current one, you have to make fewer replacements.Write the new functions to perform one specific task with as little overlap of their functionalities as possible. As a result, these functions contain less repetition of the same operands.
For details about addressing a software complexity check, see the documentation of the checker.
In cases when you are unable to refactor the code, address the checks through code annotations. For instance, if you are using a complex library, you might choose to annotate the checks that are raised on the library. See Annotate Code and Hide Known or Acceptable Results. When you annotate a file or function code metric, the corresponding software complexity checker is also annotated by the same comment.