Recently I've played a little bit with CppDepend - a commercial static code analysis tool for C++. Windows and Linux versions are available and you can download 14-days trial version. You can find lots of information about the program on their website, including screenshots, sample reports, and cases studies of Ogre3D and Irrlicht game engines. Here is my brief review.
First thing you have to do is to create a CppDepend project. You can add Visual Studio solutions to it and set parameters about what reports you want. Alternatively, if you don't have one beacuse e.g. you use makefiles, you can use separate tool - ProjectMaker - to manually create and save some virtual .sl "solution" that enlists source files and directories to analyze.
Then the program analyzes your code (internally using Clang) and builds a database about it. It generates report in HTML format, as well as allows browsing gathered data interactively inside the program (or inside Visual Studio if you install appropriate AddIn). Here you can see how it looks like for some of my code, combined The Final Quest 7 and CommonLib. First of all, you can browse tree of projects, namespaces, classes and methods:
A HTML raport is generated with the list of found issues:
You can visualize different kinds of relationships like inheritance or just using one type by another as a graph:
Another way to visualize dependencies is matrix:
Yet another view mode is treemap. Here I displayed methods (grouped in classes and modules) where size of a method is dependent on number of lines of code.
You can perform simple search and sorting of projects, namespaces, types, methods and files by name, size and different other metrics. Matched items are highlighted on the treemap.
Finally, you can issue complex queries using CQLinq - a query language based on C# LINQ syntax. Embedded query editor is available with syntax highlighting, autocompletion and immediate query output as you type.
So what kinds of data does the program gather from your code? A lot of. Even such simple thing as number of lines of code is calculated intelligently. Instead of text-based, these are logical LOC, which count sequence points in code, so they are independent of coding style, like braces placement or spanning function call on several lines of code.
I didn't mess with code metrics before, so it was interesting for me to read what does it mean for a piece of code to be "stable" or "abstract". It turns out that the code is stable if its types are used by a lot of types of third-party modules. On the other hand, code is abstract when it contains a lot of abstract classes and interfaces. Code that is stable but not abstract can be painful to modify. Code that is not stable and very abstract is useless. Sounds like an interesting idea :)
Another interesting metric is Cyclomatic Complexity. It is basically a number of decision that can be taken in a function, that is number of: if, while, for, case, default, continue, goto, catch etc. Lack of Cohesion Of Methods (LCOM) is yet another metric. It can indicate quality of a class. It is low when almost every methods in the class uses every field, which is good. It is high when, for example, every method uses only one field (like when class has only getters and setters), which is bad.
Based on these metrics (and many others) and some predefined rules, a list of issues found in the code is enlisted in the report. Some of them are very valuable, some not so much. For example, code matching the rule "Constructor should not call a virtual methods" is obviosly a bug or at least a bad practice. But the rule "Fields should be declared as private" seems a little too restrictive, especially as it matches also globals like const float PI = 3.14.
Generally, it feels great to have analysis based on both physical aspect (like directory structures, source files, comments) and logical aspect of the code (like class inheritance, public versus private, number of nested loops). It's also great that the program analyzes code on all levels, from whole solution depending on external (and possibly unknown) code like Windows.h, through namespaces, classes and methods, down until analyzing code inside functions, counting number of conditions, loops, local variables and analyzing which classes and methods are used by which.
Static code analysis tool like CppDepend is not one of the tools necessary for programming, like editor, compiler or debugger. But I believe it can be useful in at least following applications:
When thinking about a conclusion, I have this thought based on some blogs posts I've read recently (here is the first one, unfortunately I can't find the other one right now) that there is a spectrum of different types of programmers. On one side, there are these very "good", rockstar programmers who are not as good at teamwork and instead of solving real practical problems, they play around with code, talk about theory (whether algorithms or language standard) and write so sophisticated code (e.g. with elaborate C++ template tricks) that it is hard to read and maintain for others. They don't bother to give their variables some meaningful names or split their code into clear modules and classes. On the other side of the spectrum there is the growing number of bad programmers who graduate computer science because they were told to do so (with a promise for good money, lots of jobs or anything) and have no real talent, passion or even basic willingness to learn this profession. They only glue their code using ready frameworks, design patterns and code found on Google using Ctrl+C Ctrl+V. I can see clear relationship between this spectrum and the seriousness with which we take reports about code metrics like these genetared by CppDepend. I also believe that in both cases the best approach lies somewhere in the middle.
Appendix: Clang Rocks! is an interesting article by Issam Lahlali, CppDepend lead developer, that explains how they use Clang frontend to analyze C++ code in their product.
Update: CppDepend v2017 has been released recently, adding many great features, including the following: