Clear as Mud :

When it comes to working with code metrics, one of the least understood aspects seems to be cyclomatic complexity.  To shed some light on the subject we need to examine  function complexity measures, and specifically the correct basis for the well-known Cyclomatic Complexity (CYC) metric. I will take a deeper dive into this topic to offer a better

understanding of this key measure of code complexity.

CYC is one of the most common metrics used to measure software quality. It is defined by McCabe as a measure of the amount of decision logic in a single software module. In its simplest form, it is a count of the number of decisions in the source code: the higher the count, the more complex the code.  It can be used in two ways: to limit code complexity, and to determine the number of test cases required.

Controversy arises through the often-quoted value of the limiting factor of 10 (decisions) and, most particularly, in the method of calculation. The calculation is derived from the control flow graph:

Cyclomatic Complexity = E – N + 2P

where:

P = number of disconnected parts of the flow graph (e.g. a calling program and a subroutine)

E = number of edges (transfers of control)

N = number of nodes (sequential group of statements containing only one transfer of control)

This translates to the number of decisions + 1.

Binary decisions, such as “if” and “while” statements add one to complexity. Boolean operators add either one or nothing to complexity, depending on whether they have short-circuit evaluation semantics that can lead to conditional execution of side-effects.

Example:

There is one decision, therefore CYC = 2

However, considering the side effects caused by the boolean operator, there are actually two decisions.

-

Thus CYC = 3

It is possible, under special circumstances, to generate control flow graphs that do not model the execution semantics of boolean operators in a language. This is known as “suppressing” short-circuit operators or “expanding” full-evaluating operators.  STCYC calculation in static code analysis tools such as PRQA is based on statements alone, suppressing short-circuit operators.

This choice gives a good high-level view of control flow by hiding the details of the encapsulated and often unstructured expression-level control flow.

However, this representation is not effective for testing (unless perhaps it is first verified that the short-circuit boolean expressions do not contain any side effects).

A more effect metric for testing purposes  is Myers’s Interval which is an extension to cyclomatic complexity and proposed by Myers in 1977. It uses a cyclomatic complexity interval to take into account the additional complexity caused by compound predicates. It uses CYC as its lower bound and the upper bound is defined as the total number of conditions in the code +1 and is presented as two values separated by:

CYCLOMATIC COMPLEXITY : NUMBER OF LOGICAL OPERATORS

For example:

The example above has a STMCC value of 3:4 because its CYC is 3 and there is one connective (&&) used in the conditions.

The Bottom Line:

When it comes to cyclomatic complexity, higher numbers are “bad” and lower numbers are “good”. Cyclomatic complexity should be used to get a sense of how hard any given code may be to test, maintain, or troubleshoot as well as an indication of how likely the code will be to produce errors.  What this all means  is that a high complexity number means greater probability of errors with increased time to maintain and troubleshoot. As a result its advised that you take a closer look at any functions that have a high complexity and decide if they should be refactored to make them less complex.

Not only does code complexity impact code reuse it plays a major role in improving code security  -for more information check out the white paper ADDRESSING SECURITY VULNERABILITIES AT THE SOURCE: A GUIDE TO USING STATIC SOURCE CODE ANALYSIS TO DEVELOP MORE SECURE EMBEDDED SOFTWARE and start protecting your applications