17

I'm confusing about the CC of switch statement

If I have following code:

if (n >= 0) {
    switch(n) {
        case 0:
        case 1: 
            printf("zero or one\n");
            break;
        case 2: 
            printf("two\n");
            break;
        case 3:
        case 4: 
            printf("three or four\n");
            break;
        }
    }
else {
    printf ("negative\n");
}

what is the CC?

I found a post said that it's 5, with this diagram CC diagram

(the edges are 17, not 16, I think it's a typo)

It says that we only need to count case 0 and case 1 as one

But I think the diagram should be: CC diagram

Edges: 17,
Nodes: 13,
17 - 13 + 2P = 6

I count every cases as 1

My OOSE professor said it's 6, but in different way

He said:

init     => 1  
if       => 1  
switch   => 1  
case 0 1 => 1  
case 2   => 1  
case 3 4 => 1

so it should be 6

What's the correct answer?
I'm really confused, thanks.


edited:
Now I think it's 7. yes, 7
Because if n is more than 5, will just do nothing and exit the switch statement.

then we get this diagram:
enter image description here

now E = 18
18 - 13 + 2 = 7

am I correct..?
really, really, really confused...

CodinCat
  • 15,530
  • 5
  • 49
  • 60

3 Answers3

9

Ok, I have found the answer.

from McCabe.com, page 26 and 27

The answer is 5, because the original version of CC by McCabe counts a fall-through case as 1.

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164
CodinCat
  • 15,530
  • 5
  • 49
  • 60
  • This answer is correct by definition. McCabe defined Cyclomatic complexity (and coauthored the PDF referenced.) On p 26 of PDF we find this rule: "When several case labels apply to the same program statement, this is modeled as a single decision outcome edge in the control flow graph, adding one to complexity." – FeralReason Feb 24 '23 at 15:37
8

Code metric tools I've worked with count each case as a separate branch, even if it's a fall through case.

But this is an arbitrary choice. Code metric tools tend to err on the side of caution by default. The way the switch statement will ultimately be evaluated is an internal implementation detail that will vary based on the type of input and number of cases (at least in C#).

The go-to answer for reducing cyclomatic complexity caused by switch statements is to convert the cases/outputs into a dictionary. In your example, it would be something like the code sample below. Be aware that this is only for readability/maintainability. If your switch statement is long enough the .Net compiler will automatically convert it to a dictionary for you, so there is no performance gain.

var outputs = new Dictionary<int, string>()
            {
                { 0, "zero or one\n" },
                { 1, "zero or one\n" },
                { 2, "two\n" },
                { 3, "three or four\n" },
                { 4, "three or four\n" }
            };

if (n >= 0)
{
    printf(outputs[n]);
}
Seth
  • 706
  • 4
  • 20
  • thanks for your answer. I'm learning about Cyclomatic Complexity, and just want to know how to calculate it. – CodinCat May 14 '15 at 16:28
  • The first time I wrote a cyclomatic complexity tool (>20yrs ago) I made the same mistake - or took the same incorrect shortcut. Appreciated CodinCat reminding me of that :P – FeralReason Feb 24 '23 at 16:01
0

The correct answer is 7. Each case within the switch statement counts as 1, therefore 5 x 1 = 5. The if counts as 1. The else counts as 1. So, 1 + (5 x 1) + 1 = 7.

If you would count this as a method's body the cc would be 8 as the method counts as a straight through path.

Please change your accepted answer to the correct one as 5 is an incorrect answer.