September 2012

Warning! Some information on this page is older than 3 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

15:03
Sun
30
Sep 2012

CppDepend

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.

At first glance, program looks like typical commercial Windows application full of colourful icons, popup windows, hints and tips everywhere. They have their own, non-standard looking GUI, but it clearly resembles the one from Visual Studio, including docking side panels, error list at the bottom etc. Skin can be changed to make the program look like GUI from different versions of Microsoft Office, among others. Even the HTML report is full of JavaScript and knows better than you when you want to open a link in new window (that is, in most cases). But after getting used to it I think everything is designed reasonably and makes this powerful application really easy to use.

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.

Comments (1) | Tags: c++ tools | Author: Adam Sawicki | Share

20:14
Mon
17
Sep 2012

WeCan 2012 Demoparty

Last weekend - 14-16 September 2012 in £ód¼, Poland, there was a multiplatform demoscene party called WeCan. I've been there and I think it was great event! For more information, see these links:

My favourite production was Wave AtraKKtor - a 4k intro coded by my friend KK/DMA. He took first place. Congratulations Krzysiek! Maybe next year I will make some production for this party, whether demo or game...

Comments (0) | Tags: demoscene events competitions | Author: Adam Sawicki | Share

11:34
Sat
08
Sep 2012

Are Comments Unnecessary?

I generally believe that in programming there is often only one right way of thinking and who doesn't agree with it is just not experienced enough to understand it. That's why I avoid expressing my personal and more "philosophical" opinions about programming. But maybe I should? Tell me what you think in comments.

I was inspired to write this post by the list of 20 controversial programming opinions. It looks like a gist from discussion of many professionals. I like it a lot and agree with all of the points, except one.

In point 4 they claim that comments are a form of code duplication and should be avoided in favor of more readable code. I don't think that's true. In the perfect world all code comments would be unnecesary because programming language would be so clean and expressive that we could express our intentions directly in the code. But in reality there is always lots of bookkeeping / boilerplate code that we have to interlace with real logic to make any program work. Managed languages (like C#, Java) and scripting languages (like JavaScript, Python) do better job in reducing it than C and C++, but in exchange for performance.

Look at this very simple example. HLSL language has function reflect that calculates a reflected vector. If it didn't, we could easily code it in HLSL using vector arithmetic, like this:

float3 reflect(float3 i, float3 n) {
    return i - 2 * dot(i, n) * n;
}

Now what if we want to code same function in C or C++ and we use XNA Math as the math library? It would look like this:

XMVECTOR reflect(FXMVECTOR i, FXMVECTOR n) {
    return XMVectorSubtract(i, XMVectorScale(n, 2.f * XMVectorGetX(XMVector3Dot(i, n))));
}

Much better than if we coded it using D3DX math functions, but still not very readable. Don't you think that the formula for this calculation, expressed directly in some comment above this function, would help to understand it?

// i - 2 * dot(i, n) * n

Please also recall how algorithms look like when described in this Pascal-like pseudocode in computer science books. Now think about an algorithm for manipulating some complex data structure that you seen or written in the real code. Was it similar? I bet it was several times longer because of all this memory allocation and other stuff that had to be done to make it a working code.

Of course I agree comments that repeat what can already be seen in code are stupid.

// Creates thread.
void CreateThread();
// Number of threads.
UINT threadCount;

Even worse when comments replace good identifier names.

// Creates thread.
void Go();
// Number of threads.
UINT i;

But code doesn't tell everything. It doesn't tell whether particular pointer can or cannot be null, a time value is in seconds or milliseconds, a number has to be power of two etc. I like comments before functions and classes, especially in header files, as a form of documentation - no matter if in Doxygen format or not.

/*
i - Incident 3D vector, pointing towards the surface.
n - Normal 3D vector, perpendicular to the surface. Should be normalized.
Returned 3D vector points from the surface.
*/
XMVECTOR reflect(FXMVECTOR i, FXMVECTOR n);

I think encapsulation is everything. Even in real life, you press buttons on any device and use it without need to know all the electrical and mechanical details about what happens inside the box. In programming we want to use libraries, classes and functions just by using its public interface, without studying the underlying implementation. Hey, if we had to always deal with all the details down to the lowest level, we would never be able to build any complex system! Similarly, I'd like to see the mathematical formula or algorithm pseudocode without studying all the boilerplate that's in the real code. That's what documentation is for, that's what comments are for. And that's why I hate this saying "Want documentation? Just look at the code!"

Comments (2) | Tags: philosophy | Author: Adam Sawicki | Share

21:31
Thu
06
Sep 2012

Visual Merge Tool (P4Merge)

Perforce (or P4 for short) is a commercial version control system used in many companies instead of free CVS, SVN, Mercurial or Git. It has its pros and cons, but the included diff/merge tool is definitely its good point. It's actually the best tool of this kind I've ever seen on Windows, better than free TortoiseMerge, DiffMerge or KDiff3. It turns out that this tool is also free!

To grab it, go to Perforce Downloads and download appropriate (32-bit or 64-bit) version of the P4V: Visual Client. Then install it, but from the installation components leave only "Visual Merge Tool (P4Merge)". Now you have this great, free tool in your system.

To setup it as diff and merge tool in TortoiseGit (TortoiseSVN and others are similar I think), follow instructions from article Using P4Merge with TortoiseGit. Basically, enter TortoiseGit Settings and there:

Comments (7) | Tags: tools version control | Author: Adam Sawicki | Share

23:53
Tue
04
Sep 2012

Ribbon Runner - WGK 2012 - Games Bonanza

Last weekend (31 August - 2 September 2012) I attended 2nd edition of National Conference on Computer Games Development in Gdańsk, Poland. This time I didn't have to travel far because I now live in Gdańsk :) It was great to see face-to-face again all these people from Polish gamedev and Warsztat community. Lectures were interesting (well, at least some of them :) There were other attractions too like poster session or Developers Showcase, where developers presented their game projects.

I spent sunday participating in Games Bonanza - a competition where teams of up to 4 people had to develop a game in 8 hours... and we took first place! Thanks for voting for us. The theme this year was "space-time warp", so we came up with an idea for a game which is 2D, but played on a 3D surface that folds, tars and glues like a sheet of paper. Here is a video from our game:

Title of the game - "Ribbon Runner", as well as name of our team - "';DROP TABLE uczestnicy --" we came up in a hurry. Our team was:

We developed it in Visual C++ 2010 Express, using Direct3D 9 for graphics and FMOD library for sound. As a base we used framework prepared by Krzysiek. You can download full source code here: WGK2012.ZIP (12.5 MB). In case you want to compile and run it yourself, remember that: 1) Release version crashes on level 5. 2) Levels don't finish automatically, you can switch them with F1..F9 keys.

Comments (0) | Tags: warsztat competitions events productions | Author: Adam Sawicki | Share

STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2017 Adam Sawicki
Copyright © 2004-2017 Adam Sawicki