An Update for Using PC-Lint with the Windows Driver Kit
A couple of years ago I released a tool for using Lint with the Windows Driver Kit (WDK) that was described in my NT Insider article, Another Look at Lint. For those unfamiliar with Lint, it is the checking program for the C language that came out of Bell Labs in 1978. My tool supports Gimpel’s PC-Lint, a modern variant capable of many advanced checks for both C and C++.
I have a new version of my tool that supports all WDK’s up to the release candidate for Windows 10. The new version is an intermediate code drop; it supports all the new compilers and WDK’s but the lint definitions have not yet been tuned for the newer WDK’s. There will be another release once the Windows 10 WDK is final. You will be able to get the new version from the OSR site where the original article is located.
A lot of people think “I use /W4 and Code Analysis, so why do I need more”. If you knew three good developers and asked them to review the code if your driver, would you only pick two of them to do the review? Each of the tools uses a different approach to looking at the code, and while many of the bug reports are common to the tools, each has more than enough unique checks to make running all three tools worthwhile.
For example, the Windows 8 WDK samples are well checked by Microsoft, but Lint flags another 64K lines of warnings. Some people will say the warnings are false positives, or are things “we don’t need to worry about”, but there are a number of items we should care about. For instance:
Over 3000 variables declared but not referenced. Sure they don’t break the code, but do they represent an omission error? I.E. was there code supposed to be written, and somehow was not incorporated into the product? The over 3000 doesn’t include another roughly 7000 structure fields or object members that are not referenced, while a lot of these are.
Assignment of a variable or field around 4000 times, where the value assigned is not referenced. Again this doesn’t break anything, but it could be an omission error, or at least the programmer could get rid of the assignment.
Around 3000 functions that could be made static, improving modularization. A lot of developers don’t like static, but this does signal to both the coders and the compiler that the function is only used in this module.
Over 2200 Boolean expressions that are always constant. Yes, a number of these are intentional, but certainly not all. In previous versions of the WDK, I have encountered large code blocks that could never be executed. The compiler will remove them as dead code, but do you really want that when you are working on or reviewing the code?
The above is far from a complete list of items flagged. None of these are real errors, but do you really want these in code you are going to take for one of your drivers? One of the good things about static checking tools is the more a developer uses them and actually changes the code to fix the warnings (versus just suppressing the warnings with a #pragma), the more one evolves their coding style to eliminate the warnings in the first place.
The issue about static checking tools is that so many developers view fixing the warnings or adding the annotations as just another chore that has to be done. I view it as an opportunity to review the code from a different perspective. When I am fixing a warning from one of the tools, I am looking at the code around the problem to see both why the problem occurred, and what other improvements can be done to the driver in that area. The approach of using the various language checking tools and reviewing code is in itself a large topic that will be covered in a future blog post.