In practical terms higher cyclomatic complexity means one has to create more test cases to check a unit of code.
OK so this is for automated testing.
That 500 line function is a large switch statement, with each branch of it containing lots of weird code, picking out the values out of GPS packets of different kinds.'500 lines' and 'weird code' are immediate red flags to me. As a general rule of thumb I limit the size of a function so that I can see it all on the screen at once without having to scroll. In my case that's about 60 lines of code.
In my case that's about 60 lines of code.
I can see a clever coder would have made it table-driven, with tables of offsets into the packets for different values (…)Table-based state machines, some cases of LUTs and similar solutions may bring down the cyclomatic complexity value as calculated by an automated analyzer. But this is just “cheating” in the metrics. Not really improving them.
An analyzer is a naïve tool, which counts conditionals.(1) You can “hide” conditionals in data and thus make the tool “believe” there is less paths than there actually is. But I hope you see this is not helping in practice.
int f(int se)
{
switch(sel)
{
case 0: return 5;
case 1: return 2;
case 2: return 1;
case 3: return 77;
default: return -1;
}
}
int f_1to10(sel)
{
switch(sel)
// cases 1 to 10
}
int f_11to20(sel)
{
switch(sel)
// cases 11 to 20
}
...
int f(sel)
{
if(sel < 11)
f_1to10(sel);
else if(fuck that, you got the point
}
I don't see how to make this particular problem "simpler". I am presented with a range of packets which contain different data in different places. One has to code it "somehow".Without knowing the details of your data it is difficult to say. However, a general approach to a problem of this type might be:
1. Write a function that transforms the input into a number of data structures that are easier to process. This might be a distinct record for each type of packet if they were all very different or a smaller number of variant records (unions) if the packets contain a lot of common data types.
2. Write functions to extract values from each type of packet. GetDate, GetCoordinates etc.
3. Call the extraction routine with the parameters needed for your application.
Cyclomatic complexity isn’t a proxy variable, which was chosen merely because somebody noticed a correlation with the value of interest.(1) CC has been constructed as a mathematical formulation of the measured value itself. This gives it a strong theoretical foundation.
But corner cases are rare and can’t be used to explain a large number of functions having high CC
CC gives a fairly precise indication about the number of test-cases for white-box branch coverage.
Either you have test coverage or you don't. If you have coverage you don't CC to tell you how many test cases you need
I do not know, what kind of grime cyclomatic complexity has accumulated in the past 40 years. Given how inventive “we will sell you the next great management methodology” people are, I assume you might have heard some wild promises about CC.
But here, in this thread, we talked about how high CC numbers indicate problems with — specifically — code testability and maintainability.
Far from it. Here's an exercise for you to do which illustrates how transforming data makes it easier to work with. You are old enough (but not too old I hope ;)) to remember dealing with pounds, shillings and pence (LSD). Write a handful of functions to be used in an application that has numerous instances of:Quote1. Write a function that transforms the input into a number of data structures that are easier to process.Only an expert programmer is going to understand that sort of code :)
Monkeys(){while !sonnet{sonnet+=random(asciiCharacter)}return sonnet}
CC: What is more 'complex', Shakespeare or an infinite number of monkeys with typewriters? Surley the monkeys are just a function that concatenates random letters in an infinite loop. What could have a lower CC than this function?
That is true, but I'm not sure why it's so important. Either you have test coverage or you don't. If you have coverage you don't CC to tell you how many test cases you need.
I can see a clever coder would have made it table-driven, with tables of offsets into the packets for different values (…)Table-based state machines, some cases of LUTs and similar solutions may bring down the cyclomatic complexity value as calculated by an automated analyzer. But this is just “cheating” in the metrics. Not really improving them.
Either you have test coverage or you don't.
But anybody that has metrics as a goal is in a state of sin.Of course. Confusing benchmarks with what they measure is a common mistake. Ubiquitous far beyond tech world. Police focusing on improving stats, pupils made aiming for universally high grades, authorities trying to make bad-looking values zero. People are people and misuse of tools is widespread.
Either you have test coverage or you don't.
I've seen projects with an imposed/mandated requirement for 70% code coverage. That percentage was measured using commercial tools.
The tests didn't actually indicate whether the code did the right thing; the code was executed and that was what mattered. Isn't it?
Either you have test coverage or you don't.
I've seen projects with an imposed/mandated requirement for 70% code coverage. That percentage was measured using commercial tools.
The tests didn't actually indicate whether the code did the right thing; the code was executed and that was what mattered. Isn't it?
Well, yes, code coverage is just a guarantee that a certain % of the code is going to be executed during testing. That's all there is to it.
It obviously doesn't guarantee that the covered code is correct.
But what it does say is that anything below 100% coverage means that at least some parts of the code are NEVER executed during testing, which means it's fully unknown territory.
This is how code coverage should be interpreted.