Introduction

The Cyclomatic Complexity Metric[1] "measures the amount of decision logic in a single software module"[2]. In my implementation I have taken the software module to be a function. The cyclomatic complexity "is based entirely on the structure of the software's control flow graph" [2]. The formula for calculating the cyclomatic complexity for each function using its control flow graph is:

where E and N are the number of edges and nodes in the control flow graph, respectively. Figure 1 displays the control flow graphs for the control structures found in the C++ language except for for. My understanding of the Cyclomatic Complexity Metric is that it measures how complex a function is and this determines how easy it will be to test the specific function.

if

if/else

while

do

switch

Figure 1. Control flow graphs

Background

At last after nearly five years of working on this add-in, I have finally released it. Why five years you may ask? Well after finding and implementing an algorithm to display directed graphs, improving the program, then discovering Graphviz, losing all the source code and starting from the beginning again, it has taken me that long. For the VC++ 6 version of the add-in, I have made use of Norm Almond's CLabel class. In the VS.NET 2003 version, I made use of Rashid Thadha's ATL version of the CLabel class.

Installing the Add-in

VS.NET 2003

Double-click on the ReCreateCommands.reg file to register the add-in. After installation, the following buttons should appear on the toolbar: .

If nothing appears, click on the Tools menu item and select Add-in Manager... from the dropdown menu. The Add-in Manager dialog will appear. Now make sure that both the boxes for the Available Add-ins and the Startup are selected. The toolbar should appear now.

Also look at the View\Toolbars menu item and select Metric Viewer from the list.

If still nothing appears then try devenv.exe /setup.

VC++ 6

Click on the Tools menu item and select Customize... from the dropdown menu. The Customize dialog will appear. Click on the Add-ins and Macro Files tab. Click the checkbox labeled CycloComplexViewer Add-In to enable it.

VS.NET 2003

The first button is used when you want to find out the cyclomatic complexity metric of a specific function. Just select the specific function and click the button. As shown in Figure 2(a) and 2(b), a dialog with the name of the function and its specific metric is displayed. If the metric value is greater than 10 the value is displayed in red, otherwise it is displayed in black.

The second button will calculate the cyclomatic complexity matrices of all the (global and member) functions found in the currently loaded Solution. Just click the button. As shown in Figure 3, a dialog with a list control containing all the functions in the Solution and their respective matrices is displayed.

In addition to the list, the dialog has a number of controls which can be used to manipulate the data.

Figure 4 shows the control that is used to set the metric level for comparisons. Initially it is set to the default value of 10. A number of people have recommended that a value of 10 is taken as the default level against which to compare cyclomatic complexity matrices of functions. Any function with a metric value higher than 10 is considered to be too complex and needs to be broken up into a number of smaller functions. The table below gives some idea:

All functions with a metric value higher than the currently set metric level will be highlighted in the list. Figure 5 shows the results of applying the add-in to a currently loaded Solution and then setting the metric level to 5.

VC++ 6

The VC++ 6 version of the add-in can only determine the cyclomatic complexity metric for a single function. Select the function by highlighting the code for the specific function. Then click on the Add-in button and a dialog as in Figure 7 will appear displaying the metric value. If the metric value is greater than 10 the value is displayed in red, otherwise it is displayed in black.

Figure 7. Metric value of a specific selected function

Feedback

I will gladly appreciate any comments, suggestions, especially if it helps me fix the problems as stated in the Warning section.

References and Further Information

History

24 June 2005 - Added files for VC++ 6 version and updated article.

17 June 2005 - First public release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

I am a qualified Veterinary Surgeon who prefers treating computers with viruses than animals with viruses. I have recently completed a MEng German Informatics degree at the University of Reading with a 2:1. I also have the ISEB Foundation Certificate in Software Testing.

Currently I am umemployed and desparately looking for a job in the IT industry.

Comments and Discussions

I am suraj.I knew about your work and findings in the field of software engineering through website codeproject.com. I am also very interested in the field of software engineering and doing the project on the topic related to it.
I downloaded both VS.net 2003 version and Vc++6 version of your project. I couldnot run the vs.net 2003 version however i can partially run the vc++ version.When i build the project in vc++, it successfully compiles all the file but at the last it gives the error like

What kind of error is this? What should be done to successfully compile this project?Please help me to fix this problem.

your project can calculate the cyclomatic complexity of a program and generates the directed graph as well but that directed graph is generated in a text file. Cannot that directed graph be genearated in the GUI form and shown in separate window as in cyclomatic complexity.Except that can you generate the basis set of independent paths on the basis of generated directed graph.
I seek the answer of these questions because i am doing a project on "generation of basis set of paths for path testing(white box testing)".
If you could do whatever I have mentioned above, I will be very helpful for my project.And if possible,can you provide the documentation of your project to me for the reference purpose ?

you havenot included the "for loop" in your project. Why? doesnot it affect the computation of cyclomatic complexity.Similary, the control flow graph for "while loop" given by you and given in the book of Roger S. Pressman ,fifth edition is different? which is the correct one?

I hope that you will respone my mail and willnot make me disappointed.
I look forward to hearing from you very soon.
Thanking you
suraj

I have downloaded the dll for .NET. I tried to use the same. But i was not able to use. I went through code and found that it has developed for 7.1.
I tried to build at my local machine. It is giving lot of errors.

Could you please provide me the dll which will be compatible with Visual studio 8.0?

I downloaded the code, and tried to compile it. There are a couple things that seem to be missing.
- The solution file references a setup project which is not included.
- The project settings call for linking to a cximagecrtd.lib which is not there.

I am able to remove the setup project with no problem, but I cannot find any reference on the Internet to a cximagecrt

Apologies. What worked with the VC 6 version doesn't with VS .NET 2003. The CXImagecrtd.lib comes from the CxImage library found at http://www.xdp.it/cximage.htm[^]. Unfortunately the author is not supporting it any more.

OK, I got it going, though I still haven't got the "Entire solution" part to work successfully. Also, the dialog box that pops up doesn't have that nice coloring and large text for the complexity number.

Related to the problems you mention in the "Warning" section, you may consider using lex/yacc utilities or their Flex/Bison equivalents. They greatly simplify the task of creating parsers and compilers.The Lex & Yacc Page[^]

[UPDATE] Forget about the above paragraph. Looking at the list of your articles I can see you are fully aware of these tools

Besides, if you only want to obtain the metrics, chapter V in "A Complexity Measure, by McCabe[^] points to a handy simplification in the case of structured programs: instead of calculating the complexity from the graph structure (the edges and nodes formula), it's easier to calculate it as the number of decision control keywords (if, while, for, etc.) plus one. Strictly speaking, you'd also need to look into the conditions governing those keywords.

Quote:In practice compound predicates such asIF "C1 AND C2" THEN are treated as contributing two to complexity since without the connective ANDwe would have IF C1 THEN IF C2 THENwhich has two predicates.

This means you'd also need to add one for every logical operator inside a condition immediately after a decision control keyword.

With this in mind, once the parser recognizes it's inside a particular function, and until its end, it just needs to count the relevant keywords, the logical operators in their conditions (which are right after each keyword), and add one at the end. It doesn't actually need to recognize and make sense of each and every sintactical piece.

I tried Lex and Yacc but I am a bit incompetent in that department. It was only after I had completed all the code
and was busy testing that I found out about the method of counting the number of ifs, for, .... and adding one. Thanks for the suggestions