Know your compiler warnings

Human error/judgement can sprinkle a wide variety of bugs in our code base and the process of discovery, verifying it is indeed a bug, then making changes, testing and deployment is costly. Not to mention the lost productivity of your clients.  Some bugs only present themselves when put under pressure, others show up in multithreaded scenarios and some show up when we change resources. There are so many moving parts and logical paths our code can take that there’s always a bug lurking even with good unit testing and code coverage.

On one side you might have a small CSS display issue causing a page to render incorrectly and the other extreme where a bug such as heartbleed cost economies around the world millions of dollars and went unnoticed for three years. If you think about your place of work and the cycle you and your team go through when a bug is reported. It might come through a helpdesk as a support ticket or it might be a direct call to your manager who then passes the information on to another person to verify the bug exists. Then it might sit in a backlog and prioritised or if it’s urgent, a developer needs to stop what they’re doing, debug, make a fix, deploy it to staging have someone else verify the fix and then deploy it to production. If you’re one of the lucky ones who have a continuous deployment pipeline and can do deployments during the day without anyone noticing, you’ve saved yourself a little time.

Static analysis tools can reduce the risk of bugs making their way into production and the first tool you’re using on a daily basis is the compiler. Your compiler points out incorrect type usage and syntax errors and gives you that instant feedback that you’re doing something wrong. Imagine for a second that the compiler let you get away with incorrect type usage. There’d be a lot of broken software out in the wild and we’d probably find it hard to get our job done. We rely on that static analysis to tell us when we’ve made a mistake.

Compiler warnings  are something you should be interested in. It’s the compilers way of saying “This looks syntactically correct but something isn’t right and I need you to take a look for me”. I took a long hard look at a list of all the C# warnings generated by the compiler and some of them raised my eyebrows.

Take a look at Compiler Warning (level 3) CS1718 which is generated when a comparison is made to the same variable. This could be the result of a typo or a copy-paste bug and has no place in production code. It’s a no brainer, it’s a bug.

// CS1718.cs
using System;
public class Tester 
{
    public static void Main() 
    { 
        int i = 0;
        if (i == i) { // CS1718.cs
        //if (true) { 
            i++;
        }
    }
}

Compiler Warning (level 2) CS0618 generates a warning if you’re using a method which has been marked as obsolete. This could also be a method in your own code base or from a NuGet package library which indicates it might break your next build. If you have a plugin type architecture where you copy libraries into a running system (such as NopCommerce) then this could definitely cause problems. In any case, if a method has been marked obsolete you shouldn’t be using it.

// CS0618.cs
// compile with: /W:2
using System;

public class C
{
   [Obsolete("Use newMethod instead", false)]   // warn if referenced
   public static void m2()
   {
   }

   public static void newMethod()
   {
   }
}

class MyClass
{
   public static void Main()
   {
      C.m2();  // CS0618
   }
}

There’s nothing more rewarding than a purpose-built automated system pointing out potential bugs and flaws and the compiler is probably the most useful code reviewer on your team giving instant feedback. It’s no wonder C# compiler warnings are listed on MSDN under the title “C# Compiler Errors”

Turning warnings into errors

Don’t scare your team by turning all warnings into errors (yet). Turn on a few of the important ones you’ve all agreed on. In addition to the ones above, perhaps you could add another which causes a compiler error if an asynchronous task is not awaited (CS4014).

To do this, right click on your project in Visual Studio and select properties. Then click on “Build”.

specify-compiler-warnings-vs-project-properties

Final words

I’ll just briefly mention that aside from bugs, warnings tell you a lot about the quality of the code in general. Take a look at the number of compiler warnings generated by one of the many code bases at my place of employment. Does this look like a code base people care about?

compiler-warning-massive-list

I’ll dive deeper into static code analysis tools in another post but commercial code analysis tools offer a far greater scope when looking for problems and can get quite in depth and also be very expensive. Paying attention to compiler warnings is a good first step into realising the value which more expensive products provide.

If you can’t afford to spend money on tools which save money, then at least use the freebies built in to your compiler. You might end up with a good enough reason to purchase more commercial grade products or look into a DIY tool such as SonarQube.