Vector Help

Reference Manual for PC-lint® Plus

19 Living with Lint

(or Don’t Kill the Messenger)

The comments in this chapter are suggestive and subjective. They are the thoughts and opinions of only one person and for this reason are written in the first person.

When you first apply PC-lint Plus against a large C or C++ program that has not previously been linted, you will no doubt receive many more messages than you bargained for. You will perhaps feel as I felt when I first ran a Lint against a program of my own and saw how it rejected ’perfectly good’ C code; I felt I wanted to write in C, not in Lint.

Stories of Lint’s effectiveness, however, are legendary. PC-lint was, of course, passed through itself and a number of subtle errors were revealed (and continue to be revealed) in spite of exhaustive prior testing. I tested a public domain grep that I never dared use because it would mysteriously bomb. PC-lint found the problem - an uninitialized pointer.

It is not only necessary to test a program once but it should be continuously tested throughout a development/maintenance effort. Early in Lint’s development we spent a considerable effort, over several days, trying to track down a bug that Lint would have detected easily. We learned our lesson and were never again tempted to debug code before linting.

But what do you do about the mountain of messages? Separating wheat from chaff can be odious especially if done on a continuing basis. The best thing to do is to adopt a policy (a policy that initially might be quite liberal) of what messages you’re happy to live without. For example, you can inhibit all informational messages with the option -w2 . Then work to correct only the issues associated with the messages that remain. DO NOT simply suppress all warnings with something like: -e* or -w0 as this can disguise hard errors and make subsequent diagnosis very difficult. The policy can be automatically imposed by incorporating the error suppression options in a .lnt file (examples shown below) and it can gradually be strengthened as time or experience dictate.

Experience has shown that linting at full strength is best applied to new programs or new subroutines for old programs. The reasons for this is that the various decisions that a programmer has made are still fresh in mind and there is less hesitancy to change since there has been much less ’debugging investment’ in the current design. Decisions such as, for example, which objects should be signed and which unsigned, can benefit from checking at full strength.

19.1 An Example of a Policy

An example of a set of practices with which I myself can comfortably live, is as follows.

Mistaking assignment for equality is a potential problem for C/C++. If a Boolean test is made of assignment as in

if( a = f( ) ) ...          

PC-lint Plus will complain with message 720 . If the assignment is wrapped with parentheses as in

if( (a = f()) ) ...    

a different message (820 ) is used. This is done deliberately so that the programmer may distinguish between a conscious request and what appears to be accidental. Combining the assignment with testing is such a useful operation that I’m happy to put up with an extra pair of parentheses. Therefore, I suppress 820 with the option

-e820  

At one time I mixed unsigned and signed quantities with almost reckless abandon. I now have considerably more respect for the subtle nuances of these two flavors of integer and now follow a more cautious approach. I had previously employed the options

-e713 -e737    

(713 involves assigning unsigned to signed, 737 is loss of sign). These inhibitions affect only some variation of assignment. We retain warnings about mixing signed/unsigned with binary operators.

I also no longer think it is a great idea to automatically inhibit 734 (sub-integer loss of precision). This message can catch all sorts of things such as assigning int to short when int is larger than short, assigning oversize int to char, assigning too large quantities into bit fields, etc.

I suppress messages about shifting int (and long) to the left but I want to be notified when they are shifted right as this can be machine-dependent and is generally regarded as a useless and hazardous activity. Therefore, I use -e701 -e703.

I want to run my code through at least two passes so that cross-functional checks can be made. The option is -vt_passes(2).

I place my list of favorite error-suppression options in a file called options.lnt. It looks like this:

options.lnt: 
-e820           // parenthesized test of assignment 
-e701 -e703      // shifting int left is OK 
-vt_passes(2)    // use two value tracking passes

19.2 Recommended Setup

The recommended setup includes a default standard configuration (std.lnt) and a shell script (lin.bat or lin.sh) that invokes PC-lint Plus with std.lnt. The shell script might look like:

pclp64 -iC:/lint std.lnt ...  

The "lin" script needs to be placed in your executable path.

When run from most directories, the file std.lnt is found in the PC-lint Plus directory (owing to the -i option appearing in the script). This in turn includes a compiler options file and a centralized options.lnt as shown below, also found in the PC-lint Plus directory. When run from a directory that has its own std.lnt file however, the local std.lnt overrides the standard one. In this way, each project can maintain its own configuration and running PC-lint Plus from a directory that doesn’t have an explicit configuration will result in the default standard configuration being applied.

PIC

19.3 Final Thoughts

In summary, establish procedures whereby PC-lint Plus may be conveniently accessed for a variety of purposes. Lint small pieces of a project before doing the whole thing. Establish an error-message suppression policy that may initially be somewhat relaxed and can be strengthened in time. Lint full strength on new projects.

But don’t kill the messenger!