Understanding McCabe Cyclomatic Complexity

Cyclomatic complexity is a software metric used to measure how complicated a program is. Also known as Conditional complexity, it was developed by Thomas McCabe in 1976. Traditionally, it is calculated using the Control Flow graph of the program and is defined as the number of linearly independent paths through the program.

Cyclomatic in Understand

Understand reports the Cyclomatic complexity for program units (functions and methods) and reports the aggregated average and sum metrics for their containing classes and files. Metrics can be viewed directly in Understand through the Metrics Browser.  Additionally you can export metrics to a spreadsheet manually or via the command line tool “und”. The metrics treemap provides another way to view metrics using size and color.

In this treemap the complexity is represented by the darkness of the color and the size of each box represents the number of lines of code in each function.

Cyclomatic Treemap

This is a quick way to identify complicated areas of code whose modification could result in a large increase of bugs. Identifying these high risk areas is an important use of Cyclomatic complexity.

Risk Management

The Software Engineering Institute (www.sei.cmu.edu) uses the following complexity thresholds for risk management.

Cyclomatic Complexity Risk Evaluation
1-10 a simple program, without much risk
11-20 more complex, moderate risk
21-50 complex, high risk program
50+ untestable program (very high risk)

 

On the surface it might be easy to think any highly complicated program should be re-written to mitigate risk. It is one part of the equation when considering re-factoring candidates, but interconnectivity and potential impact should also be taken into account. If a complex program has run successfully for years with minimal issues, be very wary of re-writing it just to lower the complexity.

Calculating

McCabe proved that the Cyclomatic complexity of any structured program with only one entrance point and one exit point is equal to the number of decision points contained in that program plus one. Understand reports the Cyclomatic metric using this method: for a given method or function it counts the keywords for decision points (FOR, WHILE, etc) and then adds 1. For a switch statement, each ‘case’ is counted as 1 and the ‘switch’ itself adds one to the final Cyclomatic complexity count.

Understand also supports several variants for calculating this metric:

Modified Cyclomatic Complexity: Each decision in a multi-decision structure statement  (switch in C/C++) is not counted and instead the entire structure counts as 1

Strict Cyclomatic Complexity: Logical ANDs and ORs in conditional expressions also add 1 to the complexity for each of their occurrences.
i.e. The statement if (a && b || c) would have a Cyclomatic of 1 but a Strict Cyclomatic of 3

Essential Complexity: Iteratively replaces all well structured control structures with a single statement. Structures such as if-then-else and while loops are considered well structured.