views:

1283

answers:

13

Our management has recently been talking to some people selling C++ static analysis tools. Of course the sales people say they will find tons of bugs, but I'm skeptical.

How do such tools work in the real world? Do they find real bugs? Do they help more junior programmers learn?

Are they worth the trouble?

+3  A: 

Paying for most static analysis tools is probably unnecessary when there's some very good-quality free ones (unless you need some very special or specific feature provided by a commercial version). For example, see this answer I gave on another question about cppcheck.

John Feminella
+3  A: 

I've used them - PC-Lint, for example, and they did find some things. Typically they are configurable and you can tell them 'stop bothering me about xyz', if you determine that xyz really isn't an issue.

I don't know that they help junior programmers learn a lot, but they can be used as a mechanism to help tighten up the code.

I've found that a second set of (skeptical, probing for bugs) eyes and unit testing is typically where I've seen more bug catching take place.

itsmatt
When I used PC-Lint on a C++ project, I turned on the Effective C++ / More Effective C++ warnings and would re-read the section of the book when I violated one of the rules. This really helped me understand these rules in a real-world context. I found it very beneficial.
Trent
+4  A: 

It does help. I'd suggest taking a trial version and running it through a part of your codebase which you think is neglected. These tools generate a lot of false positives. Once you've waded through these, you're likely to find a buffer overrun or two that can save a lot of grief in near future. Also, try at least two/three varieties (and also some of the OpenSource stuff).

dirkgently
+1 for suggesting using a trial version. I was going to do that myself.
David Thornley
+3  A: 

Those tools do help. lint has been a great tool for C developers.

But one objection that I have is that they're batch processes that run after you've written a fair amount of code and potentially generate a lot of messages.

I think a better approach is to build such a thing into your IDE and have it point out the problem while you're writing it so you can correct it right away. Don't let those problems get into the code base in the first place.

That's the difference between the FindBugs static analysis tool for Java and IntelliJ's Inspector. I greatly prefer the latter.

duffymo
There is an Eclipse plugin for FindBugs.
Mike Daniels
Do you have an example of an interactive static analysis tool for C++? I've never seen one, but I would be interested to see one.
Tom
+2  A: 

I guess it depends quite a bit on your programming style. If you are mostly writing C code (with the occasional C++ feature) then these tools will likely be able to help (e.g. memory management, buffer overruns, ...). But if you are using more sophisticated C++ features, then the tools might get confused when trying to parse your source code (or just won't find many issues because C++ facilities are usually safer to use).

cmeerw
This is in line with my experience. When I used PC-Lint 3 or 4 years ago, it was way too noisy, and even after dialing it back, it was complaining about way too many things that were not problems.
Brian Neal
This was in a code base that was using fairly advanced C++ features.
Brian Neal
+16  A: 

Static code analysis is almost always worth it. The issue with an existing code base is that it will probably report far too many errors to make it useful out of the box.

I once worked on a project that had 100,000+ warnings from the compiler... no point in running Lint tools on that code base.

Using Lint tools "right" means buying into a better process (which is a good thing). One of the best jobs I had was working at a research lab where we were not allowed to check in code with warnings.

So, yes the tools are worth it... in the long term. In the short term turn your compiler warnings up to the max and see what it reports. If the code is "clean" then the time to look at lint tools is now. If the code has many warnings... prioritize and fix them. Once the code has none (or at least very few) warnings then look at Lint tools.

So, Lint tools are not going to help a poor code base, but once you have a good codebase it can help you keep it good.

Edit:

In the case of the 100,000+ warning product, it was broken down into about 60 Visual Studio projects. As each project had all of the warnings removed it was changed so that the warnings were errors, that prevented new warnings from being added to projects that had been cleaned up (or rather it let my co-worker righteously yell at any developer that checked in code without compiling it first :-)

TofuBeer
Recently I was working on a new hardware/software product at my company, I was lucky enough to convince the guy in charge to change some compiler warnings to errors. The warnings-to-error change forced everyone to get rid of these warnings.
Trevor Boyd Smith
This compiler flags change was the best I got to changing our "coding style" and "processes" without actually having to send an email mandate to everyone.
Trevor Boyd Smith
I think one of my happiest days was checking in the change to 60 projects with /W4 on them :-)
TofuBeer
/W4 --> just out of curiousity, could you elaborate about /W4?
Trevor Boyd Smith
/W4 turns the Microsoft compiler warnings up as high as they will go. For gcc I use something like 15 options :-)
TofuBeer
+1  A: 

Static analysis that finds real bugs is worth it regardless of whether it's C++ or not. Some tend to be quite noisy, but if they can catch subtle bugs like signed/unsigned comparisons causing optimizations that break your code or out of bounds array accesses, they are definitely worth the effort.

MSN
+2  A: 

You are probably going to have to deal with a good amount of false positives, particularly if your code base is large.

Most static analysis tools work using "intra-procedural analysis", which means that they consider each procedure in isolation, as opposed to "whole-program analysis" which considers the entire program.

They typically use "intra-procedural" analysis because "whole-program analysis" has to consider many paths through a program that won't actually ever happen in practice, and thus can often generate false positive results.

Intra-procedural analysis eliminates those problems by just focusing on a single procedure. In order to work, however, they usually need to introduce an "annotation language" that you use to describe meta-data for procedure arguments, return types, and object fields. For C++ those things are usually implemented via macros that you decorate things with. The annotations then describe things like "this field is never null", "this string buffer is guarded by this integer value", "this field can only be accessed by the thread labeled 'background'", etc.

The analysis tool will then take the annotations you supply and verify that the code you wrote actually conforms to the annotations. For example, if you could potentially pass a null off to something that is marked as not null, it will flag an error.

In the absence of annotations, the tool needs to assume the worst, and so will report a lot of errors that aren't really errors.

Since it appears you are not using such a tool already, you should assume you are going to have to spend a considerably amount of time annotating your code to get rid of all the false positives that will initially be reported. I would run the tool initially, and count the number of errors. That should give you an estimate of how much time you will need to adopt it in your code base.

Wether or not the tool is worth it depends on your organization. What are the kinds of bugs you are bit by the most? Are they buffer overrun bugs? Are they null-dereference or memory-leak bugs? Are they threading issues? Are they "oops we didn't consider that scenario", or "we didn't test a Chineese version of our product running on a Lithuanian version of Windows 98?".

Once you figure out what the issues are, then you should know if it's worth the effort.

The tool will probably help with buffer overflow, null dereference, and memory leak bugs. There's a chance that it may help with threading bugs if it has support for "thread coloring", "effects", or "permissions" analysis. However, those types of analysis are pretty cutting-edge, and have HUGE notational burdens, so they do come with some expense. The tool probably won't help with any other type of bugs.

So, it really depends on what kind of software you write, and what kind of bugs you run into most frequently.

Scott Wisniewski
A nice feature of C++ though, is that inline functions and templates mean that a lot of information is available in a single TU. Therefore, a good static analysis tool can perform a inter-procedrual analysis for the functions that are visible in the TU.
Richard Corden
My main point is that these tools have potentially high adoption costs, and only catch a limited class bugs. That means they are not "universal" solutions. They can be crucial for some projects , and a waste of time for others.Using them should be based on individual need.
Scott Wisniewski
+2  A: 

I think static code analysis is well worth, if you are using the right tool. Recently, we tried the Coverity Tool ( bit expensive). Its awesome, it brought out many critical defects,which were not detected by lint or purify.

Also we found that, we could have avoided 35% of the customer Field defects, if we had used coverity earlier.

Now, Coverity is rolled out in my company and when ever we get a customer TR in old software version, we are running coverity against it to bring out the possible canditates for the fault before we start the analysis in a susbsytem.

Warrior
+4  A: 

In my experience with a couple of employers, Coverity Prevent for C/C++ was decidedly worth it, finding some bugs even in good developers’ code, and a lot of bugs in the worst developers’ code. Others have already covered technical aspects, so I’ll focus on the political difficulties.

First, the developers whose code need static analysis the most, are the least likely to use it voluntarily. So I’m afraid you’ll need strong management backing, in practice as well as in theory; otherwise it might end up as just a checklist item, to produce impressive metrics without actually getting bugs fixed. Any static analysis tool is going to produce false positives; you’re probably going to need to dedicate somebody to minimizing the annoyance from them, e.g., by triaging defects, prioritizing the checkers, and tweaking the settings. (A commercial tool should be extremely good at never showing a false positive more than once; that alone may be worth the price.) Even the genuine defects are likely to generate annoyance; my advice on this is not to worry about, e.g., check-in comments grumbling that obviously destructive bugs are “minor.”

My biggest piece of advice is a corollary to my first law, above: Take the cheap shots first, and look at the painfully obvious bugs from your worst developers. Some of these might even have been found by compiler warnings, but a lot of bugs can slip through those cracks, e.g., when they’re suppressed by command-line options. Really blatant bugs can be politically useful, e.g., with a Top Ten List of the funniest defects, which can concentrate minds wonderfully, if used carefully.

Flash Sheridan
+1  A: 

As with everything the answer depends ... if you are the sole developer working on a knitting-pattern-pretty-printer for you grandma you'll probably do not want to buy any static analysis tools. If you are having a medium sized project for software that will go into something important and maybe on top of that you have a tight schedule, you might want to invest a little bit now that saves you much more later on.

I recently wrote a general rant on this: http://www.redlizards.com/blog/?p=29

I should write part 2 as soon as time permits, but in general do some rough calculations whether it is worth it for you:

  • how much time spent on debugging?
  • how many resources bound?
  • what percentage could have been found by static analysis?
  • costs for tool setup?
  • purchase price?
  • peace of mind? :-)

My personal take is also:

  • get static analysis in early

    • early in the project
    • early in the development cycle
    • early as in really early (before nightly build and subsequent testing)
  • provide the developer with the ability to use static analysis himself

    • nobody likes to be told by test engineers or some anonymous tool what they did wrong yesterday
    • less debugging makes a developer happy :-)
    • provides a good way of learning about (subtle) pitfalls without embarrassment
+2  A: 

As a couple people remarked, if you run a static analysis tool full bore on most applications, you will get a lot of warnings, some of them may be false positives or may not lead to an exploitable defect. It is that experience that leads to a perception that these types of tools are noisy and perhaps a waste of time. However, there are warnings that will highlight a real and potentially dangerous defects that can lead to security, reliability, or correctness issues and for many teams, those issues are important to fix and may be nearly impossible to discover via testing.

That said, static analysis tools can be profoundly helpful, but applying them to an existing codebase requires a little strategy. Here are a couple of tips that might help you..

1) Don't turn everything on at once, decide on an initial set of defects, turn those analyses on and fix them across your code base.

2) When you are addressing a class of defects, help your entire development team to understand what the defect is, why it's important and how to code to defend against that defect.

3) Work to clear the codebase completely of that class of defects.

4) Once this class of issues have been fixed, introduce a mechanism to stay in that zero issue state. Luckily, it is much easier make sure you are not re-introducing an error if you are at a baseline has no errors.

Sean
A: 

When talking about C++ code analysis, we think only to tools finding implementation problems, but other tools can help to understand the existing code and find architecture and design problems.

For example CppDepend can help to discover the existing C\C++ code base and provides a CQL language like SQL for database to query the code, and can help to detect high coupling and low cohesion.

Issam