Taming software complexity

March 3, 2008

Also note that "edges" include the flow between two sequential statements. Thus adding non-branching/non-looping statements doesn't change v(G), which is essentially the number of paths through a program. Hopefully that last statement illuminated a light bulb in your head with regards to testing. More on this later.

Limits
It's reasonable to assume (and experience proves) that functions with high cyclomatic complexities will be buggier than simpler functions. In fact, HP found a correlation coefficient of 0.8 between v(G) and defect density (www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1989-04.pdf). But it's impossible to define a single value of it that separates good functions from bad ones. Think of cyclomatic complexity like the canary in a mine. It's an early warning that the function may be difficult to maintain and error prone.

Long ago, George A. Miller ("The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information," Psychological Review, 63 (1956), 81-97) showed that humans can typically keep a maximum of five to nine things in short-term memory. That's a pretty good place to start: why write functions that are more complex than we can understand?

McCabe suggested that 10 is probably a good limiting value for v(G), and that number is certainly the most widely used. It's comfortingly close to Miller's 7±2 as well. McCabe pointed out an important exception: switch statements can generate very high-complexity metrics even in cases where the logic is pretty simple, so he suggested exempting functions with switches from complexity analysis. That rule has been interpreted in a lot of mostly dysfunctional ways and is often used to excuse many other sorts of constructs. It's better to say: "No function can exceed 10, except in cases where the resulting code would be excessively hard to understand or maintain."

Over the years, the following rules of thumb have been observed:

And:

For a variety of reasons, few companies routinely practice code inspections, which are the best tool we have for cheaply and effectively eliminating bugs. But one can use the complexity metric to flag risky routines that should get an inspection. I recommend sending, at the very least, any function that scores over 10 through an inspection.

Validated Software (validatedsoftware.com) certifies firmware to various safety-critical standards. Scott Nowell there tells me that on one recent project the code had an average v(G) of 4.7, suggesting that great code is composed of simple functions.

< Previous
Page 2 of 4
Next >

Loading comments...

Most Commented

Parts Search Datasheets.com

KNOWLEDGE CENTER