0 post

Posts Tagged ‘compiler warnings’


Compiler warnings, Coding standards, Code quality…oh my! (Part 2)

Posted by Alen Zukich   November 3rd, 2009

In the first blog series, we discussed the value of compiler warnings and wondered why a static analysis tool would have similar error checking features. In this installment, we want to dive deeper into this question by reviewing errors that can be found by compilers, why they matter, and what limitations compilers have in this area.

Let’s take an example of the “implicit int” rule:

int foo() {
   const x = 0;
   return x;
}

This is a situation where failure to specify a type results in this compiler warning from (gcc v.3.4.4) or Microsoft cl (v.14):

gcc -Wall -c main.c
main.c: In function `foo':
main.c:2: warning: type defaults to `int' in declaration of `x'

cl -c -Wall main.c
main.c(2) : warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int

You can’t rely on the standard C/C++ implementations to support the implicit int anymore and these compilers alert you to that.  I do have to say, I’ve never seen anyone do this in practice, but it’s nice to know it’s there.

Let’s look at another example:

void foo() {
   if (sizeof(char) < 2)  // defect - the condition is constant
   {
      /* ... */
   }
}

The issue above is that the condition is constant.  See the C99 standard for details on this (section 6.6).  If we run the cl compiler we get:

cl -c -Wall main2.c
main2.c(2) : warning C4127: conditional expression is constant

Here, the cl compiler finds the issue, gcc does not (well, at least my version).   Okay, interesting let’s take a look at a C++ example:

class A
{
   public:
   // non-virtual destructor
   ~A();
   virtual void f1();
};

With this example, if you run either gcc or cl you get the same thing:

gcc -Wall -c main3a.cpp
main3a.cpp:2: warning: `class A' has virtual functions but non-virtual destructor

cl -c -Wall main3a.cpp
main3a.cpp(7) : warning C4265: 'A' : class has virtual functions, but destructor is
not virtual instances of this class may not be destructed correctly

According to the output from both compilers, we made a boneheaded mistake and forgot to assign the destructor as virtual.  Let’s go one step further and define a new method:

void deleteA(A *a) {
   delete a;
}

This method adds a new level of complexity.  When an object of a class derived from the given one is deleted through a pointer to the given class, the destructor of the derived class is not executed, and members of the derived class are not disposed of properly.  In this case, you will not get any warnings from any compiler.  The difference here is that compilers only work within the context of the file/function.  In this case, you are out of luck with compilers, but luckily source code analysis excels in this.

So, the message here is that compiler warnings are quite useful, but they do have their limitations.  Not all compilers report the same things consistently, nor do they cover analysis beyond a single function or file.  Still, make sure you run the compiler warnings, then implement static source code analysis as part of your process to go deeper and find some more complex issues in your code.

For the next blog of this series I’ll cover coding standards and where they fit in your code quality process.


Compiler warnings, Coding standards, Code quality…oh my! (Part 1)

Posted by Alen Zukich   October 7th, 2009

In this 3 part blog series I want to cover general misconceptions with static analysis coverage.  This will include a discussion about:

  • compiler warnings available,
  • different types of style issues including coding standards, and
  • your available options to fit them into your formal process.

Very often customers ask why we don’t cover specific checkers.  We always get great feedback on high value checkers that they would like to see.  But occasionally we get the request to find simple compiler warnings or code style issues.

For the first part of this series I want to focus on compiler warnings.  These are not the compiler errors such as syntax/parse errors you get with a compiler.  Instead, I want to concentrate on those pesky compiler warnings that still let you build your application, when you really know you shouldn’t.  We have all experienced compiler warnings that are just plain confused with your code.  But on the whole, you are guaranteed to find some pretty big blunders.

Most modern compilers focus on providing more details about compiler warnings.  These can be very valuable as it helps find many of those plain dumb mistakes.  It varies by compilers, but many find things such as constant expressions from conditionals, returning from a void function, assignment in condition (use = instead of ==), suspiciously-placed semi-colon and many, many more.

To find some of the issues, you usually need to provide a compiler flag -Wall.  For example:

    gcc -c -Wall foo.c 

Make sure you read your compiler documentation for available warnings.  Here is the gnu gcc compiler and Microsoft cl compiler docs.

Given that every compiler on the market provides its own “checkers” for compiler issues, does it really make sense for static analysis to get in there and detect these issues again?  I strongly believe that every developer should ALWAYS clean up their compiler warnings before going onto static analysis.

But you will still find static analysis tools providing these capabilities.  Why?  Well, first and foremost, not every compiler has the capability to find simple coding issues.  The other reality is that not everyone checks the compiler warnings…(we all know who we are).  Or sometimes you just want to run one tool.  In other words get the more complex bugs with static analysis along with the compiler warnings.  It is for these reasons that static analysis tools have introduced many of these low-level issues.

For the next part of this blog series, I want to go into the details of compiler warnings and some of the things that coding standards are doing as well.