How this instrument works
Cyclomatic complexity counts the number of linearly independent paths through a routine's control-flow graph, and Thomas McCabe gave it a compact closed form: M = E − N + 2P, where E is the edge count, N the node count, and P the number of separate connected pieces in the graph. For a single subroutine — the common case, with P = 1 — the formula reduces to M = E − N + 2, and that number turns out to equal exactly one more than the count of decision points (if, while, for, and case branches) in the code.
The shape of the formula comes straight out of graph theory. The ordinary cyclomatic number of a graph, sometimes called its circuit rank, is edges minus nodes plus components, and it counts the independent cycles you would have to cut to reduce the graph to a tree with no loops left. A control-flow graph is not naturally a loop: each routine has one entry and one exit. Add a single virtual edge from every component's exit back to its own entry, closing the flow into a cycle, and the plain circuit-rank formula applied to that closed graph works out to E − N + 2P for the original, open one — McCabe's version has that construction already folded in.
The lower bound is worth knowing. A single connected piece with no branching at all — one straight run of statements, so E = N − 1 — always gives M = 1, the floor of the metric. Every extra decision point, whether an if, a case label, or a loop test, adds exactly one more edge and one more independent path, so the score climbs by exactly one per branch. That is the practical payoff: the result names the minimum number of test cases needed to exercise every branch of the routine at least once, not a rough estimate of it.
- Count the arrows on your control-flow graph — every possible jump between statements — and enter that total in Edges, E.
- Count the graph's boxes, one per statement or decision block, and enter that total in Nodes, N.
- Enter how many separate, unconnected pieces the graph has in Connected components, P; a single routine analysed alone is almost always 1.
- Read Cyclomatic complexity, M — McCabe's count of independent paths through the routine, and the floor on how many test cases full branch coverage needs.
Worked example — a 10-edge, 8-node routine
Take a single function whose control-flow graph has 10 edges and 8 nodes, drawn as one connected piece, so P = 1. The score works out to M = E − N + 2P = 10 − 8 + 2(1) = 4. That reading says the routine has exactly four linearly independent paths through it, and a test suite needs at least four well-chosen cases to exercise every one of them — fewer, and some branch of the logic goes untested.
Four sits in a comfortable mid-range for one routine: testable at a glance, with roughly three branch points beyond the single straight-through path every function starts with. Push the same function toward 12 edges and 8 nodes while splitting it into two disconnected pieces instead — P = 2, say two independent helper routines counted together — and the score rises to 12 − 8 + 2(2) = 8, since each extra component contributes a further two on top of the branching itself.
Questions
What does a cyclomatic complexity score actually measure?
It counts the linearly independent paths through a routine's control-flow graph — equivalently, the minimum number of test cases needed to execute every branch at least once. A result of 4, for instance, means four paths and a four-case floor for full branch coverage; it says nothing about readability or bug risk directly, only about branching structure.
Why does the formula use E minus N plus 2P instead of just counting branches?
Counting branches by hand gets error-prone once code has nested loops and early returns; the graph form is exact and mechanical. E − N + 2P comes from circuit rank in graph theory — edges minus nodes plus components counts independent cycles in a graph, and McCabe's extra P closes each routine's flow into a loop before that count applies, which is what the 2P rather than a plain P captures.
What cyclomatic complexity score counts as too high?
There is no formula for that threshold, only convention. McCabe's own 1976 work, later formalised in NIST Special Publication 500-235, suggested 10 as a practical ceiling for a single routine — a limit chosen from field testing experience, not derived mathematically. Many teams still treat 10 as the point to consider splitting a routine, and 20 or higher as a near-mandatory refactor.
Does connected components, P, ever go above 1 in practice?
Rarely for a single function, since ordinary code has one entry and one exit and so forms a single connected graph. P climbs above 1 when several independent routines, or a routine with genuinely unreachable code split off from its main flow, get measured together as one graph — each extra disconnected piece contributes its own additional 2 to the total.
How is this different from just counting if-statements?
For a single connected routine, P = 1, the two nearly coincide: the score equals the decision-point count plus one, so tallying branches by eye gives almost the same answer. The graph form stays the reliable one, since it also accounts correctly for compound conditions, switch ladders, and short-circuit boolean operators, which a naive branch count tends to mishandle.
Can the result ever come out below 1?
No — one is the mathematical floor. A single straight-line routine with no branching at all has exactly N − 1 edges for N nodes, and E − N + 2P collapses to 1 whenever P = 1. Any routine with at least one decision point pushes the score to 2 or higher, one step up for every extra independent path it contains.