[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


6    Checking C Programs with lint

You can use the lint program to ensure that C programs do not contain syntax errors and to verify that the programs do not contain data type errors. This chapter describes most of the checking operations performed by lint, including the following:

See lint(1) for a complete list of lint options.


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


6.1    Overview of the lint Program

The lint program checks a program more carefully than some C compilers and displays messages that point out possible problems. Some of the messages require corrections to the source code; others are only informational messages and do not require corrections.

The lint command has the following syntax:

lint [ options ] [ file ... ]

options
Options to control lint checking operations.

The cc driver flags, -std, -std0, and -std1 are available as options to lint. These flags affect the parsing of the source as well as the selection of the lint library to use. Selecting either the -std or -std1 flags turns on ANSI parsing rules in lint.

When you use the -MA lint flag, -std1 is used for the C preprocessing phase and \_ANSI_C_SOURCES is defined using the -D preprocessor flag. The following table describes the action lint takes for each flag:

Lint Pre-processor Lint Lint Library
 
     
Option Switch Parsing  
-MA -std1 and -D_ANSI_C_SOURCE ANSI llib-lansi.ln
-std -std ANSI llib-lcstd.ln
-std1 -std1 ANSI llib-lcstd.ln
-std0 -std0 EXTD llib-lc.ln

Table Note: EXTD is Extended C language, also known as K&R C.

file
The name of the C language source file for lint to check. The name must have one of the following suffixes:
Suffix Description
.c C source file
.i File produced by the C preprocessor (cpp)
.ln lint library file

Note that lint library files are the result of a previous invocation of the lint program with either the -c or -o option. They are analogous to the .o files produced by the cc command when given a .c file as input. The ability to specify lint libraries as input to the lint program facilitates intermodule interface checking in large applications. Adding rules that specify the construction of lint libraries to their makefiles can make building such applications more efficient. See Section 6.10 for a discussion on how to create a lint library.

You can also specify as input a lint library that resides in one of the system's default library search directories by using the -lx option. The library name must have the following form:

llib-llibname.ln

By default, the lint program appends the extended C (K&R C) lint library (llib-lc.ln) to the list of files specified on the command line. If the -std or -std1 flag is used, it appends the standard C lint library (llib-lcstd.ln) instead.


The following additional libraries are included with the system:
Library Description Specify As
crses Checks curses library call syntax -lcrses
m Checks math library call syntax -lm
port Checks for portability with other systems -p (not -lport)
ansi Enforces ANSI C standard rules -MA (not -lansi)

If you specify no flags on the command line, the lint program checks the specified C source files and writes messages about any of the following coding problems that it finds:

The lint program also checks for syntax errors in statements in the source programs. Syntax checking is always done and is not influenced by option flags.

If lint does not report any errors, the program has correct syntax and will compile without errors. Passing that test, however, does not mean that the program will operate correctly or that the logic design of the program is accurate.

See Section 6.10 for information on how to create your own lint library.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.2    Program Flow Checking

The lint program checks for dead code, that is, parts of a program that are never executed because they cannot be reached. It writes messages about statements that do not have a label but immediately follow statements that change the program flow, such as goto, break, continue, and return.


The lint program also detects and writes messages for the following conditions:

Some programs that include these types of loops may produce correct results. These types of loops can cause problems, however.

The lint program does not recognize functions that are called but can never return to the calling program. For example, a call to exit may result in code that cannot be reached, but lint does not detect it.

Programs generated by yacc and lex may have hundreds of break statements that cannot be reached. The lint program normally writes an error message for each of these break statements. Use the -O flag to the cc command when compiling the program to eliminate the resulting object code inefficiency, so that these extra statements are not important. Use the -b flag with the lint program to prevent it from writing these messages when checking yacc and lex output code. (For information on yacc and lex, see Programming Support Tools.)


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3    Data Type Checking

The lint program enforces the type checking rules of the C language more strictly than the compiler does. In addition to the checks that the compiler makes, lint checks for potential data type errors in the following areas:

Details on each of these potential problem areas are provided in the sections that follow.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3.1    Binary Operators and Implied Assignments

The C language allows the following data types to be mixed in statements, and the compiler does not indicate an error when they are mixed:

char
short
int
long
unsigned
float
double

The C language converts data types within this group automatically to provide the programmer with more flexibility in programming. This flexibility, however, means that the programmer, not the language, must ensure that the data type mixing produces the desired result.

You can mix these data types when using them in the following ways (in the examples, alpha is type char and num is type int):

The data types of pointers must agree exactly, except that you can mix arrays of x's with pointers to x's.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3.2    Structures and Unions

The lint program checks structure operations for the following requirements:

The lint program makes similar checks for references to unions.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3.3    Function Definition and Uses

The lint program applies strict rules to function argument and return value matching. Arguments and return values must agree in type, with the following exceptions:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3.4    Enumerators

The lint program checks enumerated data type variables to ensure that they meet the following requirements:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.3.5    Type Casts

Type casts in the C language allow the program to treat data of one type as if it were data of another type. The lint program can check for type casts and write a message if it finds one.

The -wp and the -h options for the lint command line control the writing of warning messages about casts. If neither of these flags are used, lint produces warning messages about casts that may cause portability problems.

In migration checking mode, -Qc suppresses cast warning messages (see Section 6.6).


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.4    Variable and Function Checking

The lint program checks for variables and functions that are declared in a program, but not used. The lint program checks for the following errors in the use of variables and functions:

Details on each of these potential problem areas are provided in the sections that follow.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.4.1    Inconsistent Function Return

If a function returns a value under one set of conditions but not under another, you cannot predict the results of the program. The lint program checks functions for this type of behavior. For example, if both of the following statements are in a function definition, a program calling the function may or may not receive a return value:

return(expr);

.
.
.
return;

These statements cause the lint program to write the following message to point out the potential problem:

function name has return(e); and return

The lint program also checks functions for returns that are caused by reaching the end of the function code (an implied return). For example, in the following part of a function, if a tests false, checkout calls fix\(ulit and then returns with no defined return value:

checkout (a)
{
        if (a) return (3);
        fix\(ulit ();
}

These statements cause the lint program to write the following message:

function checkout has return(e); and return

If fix\(ulit, like exit, never returns, lint still writes the message even though nothing is wrong.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.4.2    Function Values That Are Not Used

The lint program checks for cases in which a function returns a value and the calling program may not use the value. If the value is never used, the function definition may be inefficient and should be examined to determine whether it should be modified or eliminated. If the value is sometimes used, the function may be returning an error code that the calling program does not check.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.4.3    Disabling Function-Related Checking

To prevent lint from checking for problems with functions, specify one or more of the following flags to the lint command:
-x Do not check for variables that are declared in an extern statement but never used.
-v Do not check for arguments to functions that are not used, except for those that are also declared as register arguments.
-u Do not check for functions and external variables that are either used and not defined, or defined and not used. Use this flag to eliminate useless messages when you are running lint on a subset of files of a larger program. (When using lint with some, but not all, files that operate together, many of the functions and variables defined in those files may not be used. Also, many functions and variables defined elsewhere may be used.)

You can also place directives in the program to control checking:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.5    Using Variables Before They Are Initialized

The lint program checks for the use of a local variable (auto and register storage classes) before a value has been assigned to it. Using a variable with an auto (automatic) or register storage class also includes taking the address of the variable. This is necessary because the program can use the variable (through its address) any time after it knows the address of the variable. Therefore, if the program does not assign a value to the variable before it finds the address of the variable, lint reports an error.

Because lint only checks the physical order of the variables and their usage in the file, it may write messages about variables that are initialized properly (in execution sequence).

The lint program recognizes and writes messages about:

Note

The operating system initializes static and extern variables to zero. Therefore, lint assumes that these variables are set to zero at the start of the program and does not check to see if they have been assigned a value when they are used. When developing a program for a system that does not do this initialization, ensure that the program sets static and extern variables to an initial value.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.6    Migration Checking

Use lint to check for all common programming techniques that might cause problems when migrating programs from 32-bit operating systems to the 64-bit Digital UNIX operating system. The -Q option provides support for checking programs written for ULTRIX and DEC OSF/1 Version 1.0 that you are migrating to 64-bit systems.

Because the -Q option disables checking for most other programming problems, you should use this option only for migration checking. Suboptions are available to suppress specific categories of checking. For example, entering -Qa suppresses the checking of pointer alignment problems. You can enter more than one suboption with the -Q option, for example, -QacP to suppress checking for pointer alignment problems, problematic type casts, and function prototype checks, respectively. For more information about migration checking, see lint(1).


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.7    Increasing Table Size

The lint command provides the -N option and related suboptions to allow you to increase the size of various internal tables at run time if the default values are not enough for your program. These tables include:

These tables are dynamically allocated by the lint program. The -N option may be used on large source files to improve performance.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.8    Portability Checking

Use lint to help ensure that you can compile and run C programs using different C language compilers and other systems.

The following sections indicate areas to check before compiling the program on another system. Checking only these areas, however, does not guarantee that the program will run on any system.

Note

The llib-port.ln library is brought in by using the -p flag, not by using the -lport flag.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.8.1    Character Uses

Some systems define characters in a C language program as signed quantities with a range from -128 to 127; other systems define characters as positive values. The lint program checks for character comparisons or assignments that may not be portable to other systems. For example, the following fragment may work on one system but fail on systems where characters always take on positive values:

char c;

.
.
.
if( ( c = getchar() ) <0 )\.\.\.

This statement causes the lint program to write the following message:

nonportable character comparison

To make the program work on systems that use positive values for characters, declare c as an integer because getchar returns integer values.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.8.2    Bit Field Uses

Bit fields may also produce problems when a program is transferred to another system. Bit fields may be signed quantities on the new system. Therefore, when constant values are assigned to a bit field, the field may be too small to hold the value. To make this assignment work on all systems, declare the bit field to be of type unsigned before assigning values to it.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.8.3    External Name Size

When changing from one type of system to another, be aware of differences in the information retained about external names during the loading process:

When transferring from one system to another, you should always take the following steps to avoid problems with loading a program:

  1. Review the requirements of each system.

  2. Run lint with the -p flag.

The -p flag tells lint to change all external symbols to lowercase and limit them to six characters while checking the input files. The messages produced indicate the terms that may need to be changed.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.8.4    Multiple Uses and Side Effects

Be careful when using complicated expressions because of the following considerations:

The following situations illustrate the types of problems that can result from these differences:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.9    Coding Errors and Coding Style Differences

Use lint to detect possible coding errors and to detect differences from the coding style that lint expects. Although coding style is mainly a matter of individual taste, examine each difference to ensure that the difference is both needed and accurate. The following sections indicate the types of coding and style problems that lint can find.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.9.1    Assignments of Long Variables to Integer Variables

If you assign variables of type long to variables of type int, the program may not work properly. The long variable is truncated to fit in the integer space and data may be lost.

An error of this type occurs frequently when a program that uses more than one typedef is converted to run on a different system.

To prevent lint from writing messages when it detects assignments of long variables to int variables, use the -a flag.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.9.2    Operator Precedence

The lint program detects possible or potential errors in operator precedence. Without parentheses to show order in complex sequences, these errors can be hard to find. For example, the following statements are not clear:

 if(x&077==0). . .   /* evaluated as: if(x & (077 == 0) ) */
                     /* should be: if( (x & 077) == 0) */

 
x<<2+40 /* evaluated as: x <<(2+40) */ /* should be: (x<<2) + 40 */ /* shift x left 42 positions */

Use parentheses to make the operation more clearly understood. If you do not, lint writes a message.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.9.3    Conflicting Declarations

The lint program writes messages about variables that are declared in inner blocks in ways that conflict with their use in outer blocks. This practice is allowed, but may cause problems in the program.

Use the -h flag with the lint program to prevent lint from checking for conflicting declarations.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.10    Creating a lint Library

For programming projects that define additional library routines, you can create an additional lint library to check the syntax of the programs. Using this library, the lint program can check the new functions in addition to the standard C language functions. Perform the following steps to create a new lint library:

  1. Create an input file that defines the new functions.

  2. Process the input file to create the lint library file.

  3. Run lint using the new library.

The following sections describe these steps.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.10.1    Creating the Input File

The following example shows an input file that defines three additional functions for lint to check.

/*LINTLIBRARY*/

 
#include <dms.h>
 
int dmsadd( rmsdes, recbuf, reclen ) int rmsdes; char *recbuf; unsigned reclen; { return 0; } int dmsclos( rmsdes) int rmsdes; { return 0; } int dmscrea( path, mode, recfm, reclen ) char *path; int mode; int recfm; unsigned reclen; { return 0; }

The input file is a text file that you create with an editor. It consists of:

Alternatively, you can create a lint library file from function prototypes. For example, assume that the dms.h file includes the following prototypes:

int dmsadd(int,
           char*,
           unsigned);
int dmsclose(int);
int dmscrea(char*,
            int,
            int,
            unsigned);

In this case, the input file contains the following:

/*LINTSTDLIB*/
#include <dms.h>

In the case where a header file may include other headers, the LINTSTDLIB command can be restricted to specific files:

/*LINTSTDLIB_dms.h*/

In this case, only prototypes declared in dms.h will be expanded. Multiple LINTSTDLIB commands can be included.

In all cases, the name of the input file must have the prefix: llib-l. For example, the name of the sample input file created in this section could be llib-ldms. When choosing the name of the file, ensure that it is not the same as any of the existing files in the /usr/ccs/lib directory.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.10.2    Creating the lint Library File

The following command creates a lint library file from the input file described in the previous section:

lint [options] -c llib_ldms.c

This command tells lint to create a lint library file, llib-ldms.ln, using the file llib-ldms.c as input. To use llib-ldms.ln as a system lint library (that is, a library specified in the -lx option of the lint command), move it to /usr/ccs/lib. Use the -std or -std1 flag to use ANSI preprocessing rules to build the library.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.10.3    Checking a Program with a New Library

To check a program using a new library, use the lint command with the following format:

lint -lpgm filename.c

The variable pgm represents the identifier for the library, and the variable filename.c represents the name of the file containing the C language source code that is to be checked. If no other flags are specified, the lint program checks the C language source code against the standard lint library in addition to checking it against the indicated special lint library.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.11    Understanding lint Error Messages

Although most error messages produced by lint are self-explanatory, certain messages may be misleading without additional explanation. Usually, once you understand what a message means, correcting the error is straightforward. The following is a list of the more ambiguous lint messages:

constant argument to NOT

A constant is used with the NOT operator (!).

This is a common coding pratice and the message does not usually indicate a problem. The following program illustrates the type of code that can generate this message:

cat x.c
 

#include <stdio.h>
#define SUCCESS    0

 
main() { int value = !SUCCESS;
 
printf("value = %d\n", value); return 0; }
lint -u x.c
 
"x.c", line 7: warning: constant argument to NOT
 
./x
 
value = 1
 

The program runs as expected, even though lint complains.

Recommended Action: Suppress these lint warning messages by using the -wC option.

constant in conditional context

A constant is used where a conditional is expected. This problem occurs often in source code, due to the way in which macros are encoded. For example:

typedef struct _dummy_q {
  int lock;
  struct _dummy_q *head, *tail;
} DUMMY_Q;

 
#define QWAIT 1 #define QNOWAIT 0 #define DEQUEUE(q, elt, wait) [1] \ for (;;) { \ simple_lock(&(q)->lock); \ if (queue_empty(&(q)->head)) \ if (wait) { [1] \ assert(q); \ simple_unlock(&(q)->lock); \ continue; \ } else \ *(elt) = 0; \ else \ dequeue_head(&(q)->head); \ simple_unlock(&(q)->lock); \ break; \ }
 
int doit(DUMMY_Q *q, int *elt) { DEQUEUE(q, elt, QNOWAIT); }

  1. The flag QWAIT or QNOWAIT is passed as the third argument (wait), and is later used in the if statement. The code is correct, but lint issues the warning because constants used in this way are normally unnecessary and often generate wasteful or unnecessary instructions. [Return to example]

Recommended Action: Suppress these lint warning messages by using the -wC option.

conversion from long may lose accuracy

A signed long is copied to a smaller entity (for example, an int). This message is not necessarily misleading, but if it occurs frequently, it may or may not indicate a coding problem, as shown in the following example.

long BuffLim = 512;         [1]

 
void foo (buffer, size) char *buffer; int size; { register int count; register int limit = size < (int)BufLimit ? size : (int)BufLim; [1]

  1. The lint program reports the conversion error, even though the appropriate (int) cast exists. [Return to example]

Recommended Action: Review code sections for which lint reports this message, or suppress the message by using the -wl option.

declaration is missing declarator

A line in the declaration section of the program contains just a semicolon (;).

Although you would not deliberately write code like this, it is easy to inadvertantly generate such code by using a macro, followed by a semicolon. If, due to conditionalization, the macro is defined as empty, this message can result.

Recommended Action: Remove the trailing semicolon.

degenerate unsigned comparison

An unsigned comparison is being performed against a signed value when the result is expected to be less than zero.

The following program illustrates this situation:

cat x.c
 

#include <stdio.h>
unsigned long offset = -1;

 
main() { if (offset < 0) { [1] puts ("code is Ok..."); return 0; } else { puts ("unsigned comparison failed..."); return 1; } }
cc -g -o x x.c
 
lint x.c
 
"x.c" line 7: warning: degenerate unsigned comparison
 
./x
 
unsigned comparison failed...
 

  1. Unsigned comparisons such as this will fail if the unsigned variable contains a negative value. The resulting code may be correct, depending upon whether the programmer intended a signed comparison. [Return to example]

Recommended Action: You can fix the previous example in two ways:

  • Add a (long) cast before offset in the if comparison.

  • Change the declaration of offset from unsigned long to long.

In certain cases, it might be necessary to cast the signed value to unsigned.


function prototype not in scope

This error is not strictly related to function prototypes, as the message implies. Actually, this error occurs from invoking any function that has not been previously declared or defined.

Recommended Action: Add the function prototype declaration.

null effect

The lint program detected a cast or statement that does nothing. The following code segments illustrate various coding practices that cause lint to generate this message:

    scsi_slot = device->ctlr_hd->slot,unit_str;     [1]

 
#define MCLUNREF(p) \ (MCLMAPPED(p) && --mclrefcnt[mtocl(p)] == 0)
 
(void) MCLUNREF(m); [2]

  1. Reason: unit_str does nothing. [Return to example]

  2. Reason: (void) is unnecessary; MCLUNREF is a macro. [Return to example]

Recommended Action: Remove unnecessary casts or statements or update macros.

possible pointer alignment problem

A pointer is used in a way that may cause an alignment problem. The following code segment illustrates the type of code that produces this message:

read(p, args, retval)
        struct proc *p;
        void *args;
        long *retval;
{
        register struct args {
                long    fdes;
                char    *cbuf;
                unsigned long  count;
        } *uap = (struct args *) args;          [1]
        struct uio auio;
        struct iovec aiov;

  1. The line *uap = (struct args *) args causes the error to be reported. Because this construct is valid and occurs throughout the kernel source, this message is filtered out. [Return to example]


precision lost in field assignment

An attempt was made to assign a constant value to a bit field when the field is too small to hold the value.

The following code segment illustrates this problem:

cat x.c
 

struct bitfield {
    unsigned int block_len : 4;
} bt;

 
void test() { bt.block_len = 0xff; }
lint -u x.c
 
"x.c", line 8: warning: precision lost in field assignment
 
cc -c -o x x.c
 

As you can see, this code compiles without error. However, because the bit field may be too small to hold the constant, the results may not be what the programmer intended and a run-time error may occur.

Recommended Action: Change the bit field size or assign a different constant value.

unsigned comparison with 0

An unsigned comparison is being performed against zero when the result is expected to be equal to or greater than zero.

The following program illustrates this situation:

cat z.c
 

#include <stdio.h>
unsigned offset = -1;

 
main() { if (offset > 0) { [1] puts("unsigned comparison with 0 Failed"); return 1; } else { puts("unsigned comparison with 0 is Ok"); return 0; } }
cc -o z z.c
 
lint z.c
 
"z.c", line 7: warning: unsigned comparison with 0?
 
./z
 
unsigned comparison with 0 Failed
 

  1. Unsigned comparisons such as this will fail if the unsigned variable contains a negative value. The resulting code may not be correct, depending on whether the programmer intended a signed comparison. [Return to example]

Recommended Action: You can fix the previous example in two ways:

  • Add an (int) cast before offset in the if comparison.

  • Change the declaration of offset from unsigned to int.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


6.12    Using Warning Class Options to Suppress lint Messages

Several lint warning classes have been added to the lint program to allow the suppression of messages associated with constants used in conditionals, portability, and prototype checks. By using the warning class option to the lint command, you can suppress messages in any of the warning classes.

The warning class option has the following format:

-wclass [ class... ]

All warning classes are active by default, but may be individually deactivated by including the appropriate option as part of the class argument. Table 6-1 lists the individual options.

Note

Several lint messages are dependent on more than one warning class. Therefore, you may need to specify several warning classes for the message to be suppressed. Notes in Table 6-1 indicate which messages can only be suppressed by specifying multiple warning classes.

For example, because lint messages related to constants in conditional expressions do not necessarily indicate a coding problem (as described in Section 6.11), you may decide to use the -wC option to suppress them.


The -wC option suppresses the following messages:

  • constant argument to NOT

  • constant in conditional context

Because many of the messages associated with portability checks are related to non-ANSI compilers and limit restrictions that do not exist in the C compiler for Digital UNIX, you can use the -wp option to suppress them. The -wp option suppresses the following messages:

  • ambiguous assignment for non-ansi compilers

  • illegal cast in a constant expression

  • long in case or switch statement may be truncated in non-ansi compilers

  • nonportable character comparison

  • possible pointer alignment problem, op %s

  • precision lost in assignment to (sign-extended?) field

  • precision lost in field assignment

  • too many characters in character constant

Although the use of function prototypes is a recommended coding practice (as described in Section 6.12.1), many programs do not include them. You can use the -wP option to suppress prototype checks. The -wP option suppresses the following messages:

  • function prototype not in scope

  • mismatched type in function argument

  • mix of old and new style function declaration

  • old style argument declaration

  • use of old-style function definition in presence of prototype


Table 6-1: lint Warning Classes

Warning Class Description of Class
a Non-ANSI features. Suppresses:
  · Partially elided initialization [Table Note 1]
  · Static function %s not defined or used [Table Note 1]
   
 
 
   
c Comparisons with unsigned values. Suppresses:
  · Comparison of unsigned with negative constant
  · Degenerate unsigned comparison
  · Unsigned comparison with 0?
   
 
 
   
d Declaration consistency. Suppresses:
  · External symbol type clash for %s
  · Illegal member use: perhaps %s.%s [Table Note 2]
  · Incomplete type for %s has already been completed
  · Redeclaration of %s
  · Struct/union %s never defined [Table Note 2]
  · %s redefinition hides earlier one [Table Note 1] [Table Note 2]
   
 
 
   
h Heuristic complaints. Suppresses:
  · Constant argument to NOT [Table Note 4]
  · Constant in conditional context [Table Note 4]
  · Enumeration type clash, op %s
  · Illegal member use: perhaps %s.%s [Table Note 3]
  · Null effect [Table Note 6]
  · Possible pointer alignment problem, op %s [Table Note 5]
  · Precedence confusion possible: parenthesize! [Table Note 7]
  · Struct/union %s never defined [Table Note 3]
  · %s redefinition hides earlier one [Table Note 3]
   
 
 
   
k K&R type code expected. Suppresses:
  · Argument %s is unused in function %s [Table Note 8]
  · Function prototype not in scope [Table Note 8]
  · Partially elided initialization [Table Note 8]
  · Static function %s is not defined or used [Table Note 8]
  · %s may be used before set [Table Note 2] [Table Note 3]
  · %s redefinition hides earlier one [Table Note 2] [Table Note 3]
  · %s set but not used in function %s [Table Note 8]
   
 
 
   
l Assign long values to non-long variables. Suppresses:
  · Conversion from long may lose accuracy
  · Conversion to long may sign-extend incorrectly
   
 
 
   
n Null-effect code. Suppresses:
  · Null effect [Table Note 2]
   
 
 
   
o Unknown order of evaluation. Suppresses:
  · Precedence confusion possible: parenthesize! [Table Note 2]
  · %s evaluation order undefined
   
 
 
   
p Various portability concerns. Suppresses:
  · Ambiguous assignment for non-ansi compilers
  · Illegal cast in a constant expression
  · Long in case or switch statement may be truncated in
  non-ansi compilers
  · Nonportable character comparison
  · Possible pointer alignment problem, op %s [Table Note 2]
  · Precision lost in assignment to (sign-extended?) field
  · Precision lost in field assignment
  · Too many characters in character constant
   
 
 
   
r Return statement consistency. Suppresses:
  · Function %s has return(e); and return;
  · Function %s must return a value
  · main() returns random value to invocation environment
   
 
 
   
S Storage capacity checks. Suppresses:
  · Array not large enough to store terminating null
  · Constant value (0x%x) exceeds (0x%x)
   
 
 
   
u Proper usage of variables and functions. Suppresses:
  · Argument %s unused in function %s [Table Note 1]
  · Static function %s not defined or used [Table Note 1]
  · %s set but not used in function %s [Table Note 1]
  · %s unused in function %s [Table Note 8]
   
 
 
   
A Activate all warnings. Default option in lint script. Specifying another A class toggles the setting of all classes.
   
 
 
   
C Constants occurring in conditionals. Suppresses:
  · Constant argument to NOT [Table Note 2]
  · Constant in conditional context [Table Note 2]
   
 
 
   
D External declarations are never used. Suppresses:
  · Static %s %s unused
   
 
 
   
O Obsolescent features. Suppresses:
  · Storage class not the first type specifier
   
 
 
   
P Prototype checks. Suppresses:
  · Function prototype not in scope [Table Note 1]
  · Mismatched type in function argument
  · Mix of old and new style function declaration
  · Old style argument declaration [Table Note 1]
  · Use of old-style function definition in presence of prototype
   
 
 
   
R Detection of unreachable code. Suppresses:
  · Statement not reached

Table notes:

  1. You can also suppress this message by deactivating the k warning class.

  2. You must also deactivate the h warning class to suppress this message.

  3. You must also deactivate the d warning class to suppress this message.

  4. You must also deactivate the C warning class to suppress this message.

  5. You must also deactivate the p warning class to suppress this message.

  6. You must also deactivate the n warning class to suppress this message.

  7. You must also deactivate the o warning class to suppress this message.

  8. Other flags may also suppress these messages.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


6.12.1    Generating Function Prototypes for Compile-Time Detection of Syntax Errors

In addition to correcting the various errors reported by the lint program, Digital recommends adding function prototypes to your program for both external and static functions. These declarations provide the compiler with information it needs to check arguments and return values.

The cc compiler provides an option that automatically generates prototype declarations. By specifying the -proto[is] option for a compilation, you create an output file (with the same name as the input file but with a .H extension) that contains the function prototypes. The i option includes identifiers in the prototype, and the s option generates prototypes for static functions as well.

You can copy the function prototypes from a \.H file and place them in the appropriate locations in the source and include files.