lint Source Code Checker |
5 |
![]() |
lint issues every error and warning message produced by the C compiler. It also issues lint-specific warnings about potential bugs and portability problems. Many messages issued by lint can assist you in improving your program's effectiveness, including reducing its size and required memory.
lint is invoked on the command line, and can be invoked with multiple options. lint operates in two modes:
In enhanced mode, lint provides more detailed reporting than in basic mode. In enhanced mode, lint's capabilities include:
% lint file1.c file2.cEnhanced lint is invoked with the -Nlevel or -Ncheck option. For example, you can invoke enhanced lint as follows:
% lint -Nlevel=3 file1.c file2.clint examines code in two passes. In the first pass, lint checks for error conditions within C source files; in the second pass, it checks for inconsistencies across C source files. This process is invisible to the user unless lint is invoked with -c:
% lint -c file1.c file2.cThat command directs lint to execute the first pass only and collect information relevant to the second--about inconsistencies in definition and use across file1.c and file2.c--in intermediate files named file1.ln and file2.ln:
% ls file1.c file1.ln file2.c file2.ln |
This way, the -c option to lint is analogous to the -c option to cc, which suppresses the link editing phase of compilation. Generally speaking, lint's command-line syntax closely follows cc's.
% lint file1.ln file2.ln
the second pass is executed. lint processes any number of .c or .ln files in their command-line order. Thus,% lint file1.ln file2.ln file3.c
directs lint to check file3.c for errors internal to it and all three files for consistency.
You can specify multiple options to lint on the same command line. Options can be concatenated unless one of the options takes an argument or if the option has more than one letter:
% lint -cp -Idir1 -Idir2 file1.c file2.c
That command directs lint to:
lint recognizes many cc command-line options, including -A, -D, -E, -g, -H, -O, -P, -U, -Xa, -Xc, -Xs, -Xt, and -Y, although -g and -O are ignored. Unrecognized options are warned about and ignored.
-#
Turns on verbose mode, showing each component as it is invoked. -###
Shows each component as it is invoked, but does not actually execute it. -a
Suppresses certain messages. Refer to Table 5-5.
-b
Suppresses certain messages. Refer to Table 5-5.
-C filename
Creates a .ln file with the file name specified. These .ln files are the product of lint's first pass only. filename can be a complete path name. -c
Creates a .ln file consisting of information relevant to lint's second pass for every .c file named on the command line. The second pass is not executed. -dirout=dir
Specifies the directory dir where the lint output files (.ln files) will be placed. This option affects the -c option. -err=warn
Treats all warnings as errors. The result is that both errors and warnings cause lint to exit with a failure status. -errchk=l
Check structural arguments passed by value; Check portability to environment for which the size of long integers and pointers is 64 bits. structarg
Check structural arguments passed by value and report the cases when formal parameter type is not known. longptr64
Check portability to environment for which the size of long integers and pointers is 64 bits and the size of plain integers is 32 bits. Check assignments of pointer expressions and long integer expressions to plain integers, even when explicit cast is used. %all
Perform all of errchk's checks. %none
Perform none of errchk's checks. This is the default. no%structarg
Perform none of errchk's structarg checks. no%longptr64
Perform none of errchk's longptr64 checks.
-errchk=longptr64,structarg. -errfmt=f
Specifies the format of lint output. f can be one of the following: macro, simple, src, or tab.
The default is -errfmt=tab. Specifying -errfmt is equivalent to specifying
-errfmt=tab. -errhdr=h
Enables the reporting of certain messages for header files when used with
-Ncheck. h is a comma-separated list that consists of one or more of the following: dir, no%dir, %all, %none, %user.
The default is -errhdr=%none. Specifying -errhdr is equivalent to specifying -errhdr=%user.
% lint -errhdr=inc1 -errhdr=../inc2
checks used header files in directories inc1 and ../inc2.% lint -errhdr=%all,no%../inc
checks all used header files except those in the directory ../inc. -erroff=t
Suppresses or enables lint error messages.
The default is -erroff=%none. Specifying -erroff is equivalent to specifying -erroff=%all.
% lint -erroff=%all,no%E_ENUM_NEVER_DEF,no%E_STATIC_UNUSED
prints only the messages "enum never defined" and "static unused", and suppresses other messages.% lint -erroff=E_ENUM_NEVER_DEF,E_STATIC_UNUSED
suppresses only the messages "enum never defined" and "static unused". -errtags=a
Displays the message tag for each error message. a can be either yes or no. The default is -errtags=no. Specifying -errtags is equivalent to specifying
-errtags=yes. -F
Prints the path names as supplied on the command line rather than only their base names when referring to the .c files named on the command line. -fd
Reports about old-style function definitions or declarations. -flagsrc=file
Executes lint with options contained in the file file. Multiple options can be specified in file, one per line. -h
Suppresses certain messages. Refer to Table 5-5.
-Idir
Searches the directory dir for included header files. -k
Alter the behavior of /* LINTED [message] */ directives or NOTE(LINTED(message)) annotations. Normally, lint suppresses warning messages for the code following these directives. Instead of suppressing the messages, lint prints an additional message containing the comment inside the directive or annotation. -Ldir
Searches for a lint library in the directory dir when used with -l. -lx
Accesses the lint library llib-lx.ln. -m
Suppresses certain messages. Refer to Table 5-5.
-Ncheck=c
Checks header files for corresponding declarations; checks macros. c is a comma-separated list of checks that consists of one or more of the following: macro, extern, %all, %none, no%macro, no%extern.
The default is -Ncheck=%none. Specifying -Ncheck is equivalent to specifying -Ncheck=%all.
-Ncheck=extern,macro.% lint -Ncheck=%all,no%macro
performs all checks except macro checks. -Nlevel=n
Specifies the level of analysis for reporting problems. This option allows you to control the amount of detected errors. The higher the level, the longer the verification time. n is a number: 1, 2, 3, or 4.
By default, you create libraries in lint's basic format. If you use lint's enhanced mode, the library created will be in enhanced format, and can only be used in enhanced mode.
-V
Writes the product name and releases to standard error. -v
Suppresses certain messages. Refer to Table 5-5.
-Wfile
Write a .ln file to file, for use by cflow(1). This option disables the enhanced mode, if it is switched on. -x
Suppresses certain messages. Refer to Table 5-5.
-XCC=a
Accepts C++-style comments. In particular, // can be used to indicate the start of a comment. a can be either yes or no. The default is -XCC=no. Specifying -XCC is equivalent to specifying -XCC=yes. -Xexplicitpar=a
(SPARC) Directs lint to recognize #pragma MP directives. a can be either yes or no. The default is -Xexplicitpar=no. Specifying -Xexplicitpar is equivalent to specifying -Xexplicitpar=yes. -Xkeeptmp=a
Keeps temporary files created during linting instead of deleting them automatically. a can be either yes or no. The default is -Xkeeptmp=no. Specifying -Xkeeptmp is equivalent to specifying -Xkeeptmp=yes. -Xtemp=dir
Sets the directory for temporary files to dir. Without this option, temporary files go into /tmp. -Xtime=a
Reports the execution time for each lint pass. a can be either yes or no. The default is -Xtime=no. Specifying -Xtime is equivalent to specifying
-Xtime=yes. -Xtransition=a
Issues warnings for the differences between K&R C and Sun ANSI C. a can be either yes or no. The default is -Xtransition=no. Specifying
-Xtransition is equivalent to specifying -Xtransition=yes. -y
Treats every .c file named on the command line as if it begins with the directive /* LINTLIBRARY */ or the annotation NOTE(LINTLIBRARY). A lint library is normally created using the /* LINTLIBRARY */ directive or the NOTE(LINTLIBRARY) annotation.
lint Messages
Most of lint's messages are simple, one-line statements printed for each occurrence of the problem they diagnose. Errors detected in included files are reported multiple times by the compiler, but only once by lint, no matter how many times the file is included in other source files. Compound messages are issued for inconsistencies across files and, in a few cases, for problems within them as well. A single message describes every occurrence of the problem in the file or files being checked. When use of a lint filter (see "lint Libraries" on page 128) requires that a message be printed for each occurrence, compound diagnostics can be converted to the simple type by invoking lint with the -s option.
The Error and Warning Messages File, located in /opt/SUNWSPRO/READMEs/c_lint_messages, contains all the C compiler error and warning messages and all the lint program's messages. Many of the messages are self-explanatory. You can obtain a description of the messages and, in many cases, code examples, by searching the text file for a string from the message that was generated. See the section, "Error and Warning Messages File" on page xxv for details on using this file.
Options to Suppress Messages
You can use several lint options to suppress lint diagnostic messages. Messages can be suppressed with the -erroff option, followed by one or more tags. These mnemonic tags can be displayed with the
-errtags=yes option.
lint Message Formats
lint can, with certain options, show precise source file lines with pointers to the line position where the error occurred. The option enabling this feature is
-errfmt=f. Under this option, lint provides the following information:
Using lint on Test1.c with the option:
% lint -errfmt=src Test1.c
produces the following output:
The first warning indicates two source lines that are contradictory. The second warning shows the call stack, with the control flow leading to the error.
1 #define AA(b) AR[b+l] 2 #define B(c,d) c+AA(d) 3 4 int x=0; 5 6 int AR[10]={1,2,3,4,5,6,77,88,99,0}; 7 8 main() 9 { 10 int y=-5, z=5; 11 return B(y,z); 12 } |
Using lint on Test2.c with the option:
% lint -errfmt=macro Test2.c
produces the following output, showing the steps of macro substitution:
| return B(y,z); | ^ line 11, Test2.c | |#define B(c,d) c+AA(d) | ^ line 2, Test2.c | |#define AA(b) AR[b+l] | ^ line 1, Test2.c error: undefined symbol: l |
lint Directives
Predefined Values
The following predefinitions are valid in all modes:
Specify lint directives in the form of source code annotations by including the file note.h, for example:
#include <note.h>Lint shares the Source Code Annotations scheme with several other tools. When you install the SunSoft ANSI C Compiler, you also automatically install the file /usr/lib/note/SUNW_SPRO-lint, which contains the names of all the annotations that LockLint understands. However, the SunSoft C source code checker, lint, also checks all the files in /usr/lib/note and /opt/SUNWspro/<current-release>/note for all valid annotations.
You may specify a location other than /usr/lib/note by setting the environment variable NOTEPATH, as in:
setenv NOTEPATH $NOTEPATH:other_locationTable 5-6 lists the lint directives along with their actions.
lint Reference and Examples
This section provides reference information on lint, including checks performed by lint, lint libraries, and lint filters. Checks Performed by lint
lint-specific diagnostics are issued for three broad categories of conditions: inconsistent use, nonportable code, and questionable constructs. In this section, we review examples of lint's behavior in each of these areas, and suggest possible responses to the issues they raise. Consistency Checks
Inconsistent use of variables, arguments, and functions is checked within files as well as across them. Generally speaking, the same checks are performed for prototype uses, declarations, and parameters as lint checks for old-style functions. If your program does not use function prototypes, lint checks the number and types of parameters in each call to a function more strictly than the compiler. lint also identifies mismatches of conversion specifications and arguments in [fs]printf() and [fs]scanf() control strings.
char c; c = getchar(); if (c == EOF) ... |
short s; long l; s = l; |
int *fun(y) char *y; { return(int *)y; } |
int a[10]; main() { int i = 1; a[i++] = i; } |
if ((c = getchar()) != EOF & c != '0') |
unsigned x; if (x < 0) ... |
unsigned x; if (x > 0) ... |
if (x != 0) ...
if (u == (unsigned) -1) ...
if (u == -1U) ... |
int fun() { int a, b, x, y; (a = x) && (b == y); } |
if (x & a == 0) ... |
if (x & (a == 0)) ... |
The lint standard C library, llib-lc.ln , is appended to the lint command line by default; checks for compatibility with it can be suppressed by invoking the -n option. Other lint libraries are accessed as arguments to -l. That is:
% lint -lx file1.c file2.cdirects lint to check the usage of functions and variables in file1.c and file2.c for compatibility with the lint library llib-lx.ln. The library file, which consists only of definitions, is processed exactly as are ordinary source files and ordinary .ln files, except that functions and variables used inconsistently in the library file, or defined in the library file but not used in the source files, elicit no complaints.
To create your own lint library, insert the directive NOTE(LINTLIBRARY) at the head of a C source file, then invoke lint for that file with the -o option and the library name given to -l:
% lint -ox file1.c file2.ccauses only definitions in the source files headed by NOTE(LINTLIBRARY) to be written to the file llib-lx.ln. (Note the analogy of lint -o to cc -o.) A library can be created from a file of function prototype declarations in the same way, except that both NOTE(LINTLIBRARY) and NOTE(PROTOLIB(n))must be inserted at the head of the declarations file. If n is 1, prototype declarations are written to a library .ln file just as are old-style definitions. If n is 0, the default, the process is cancelled. Invoking lint with -y is another way of creating a lint library. The command line:
% lint -y -ox file1.c file2.ccauses each source file named on that line to be treated as if it begins with
By default, lint searches for lint libraries in the standard place. To direct lint to search for a lint library in a directory other than the standard place, specify the path of the directory with the -L option:
% lint -Ldir -lx file1.c file2.cIn enhanced mode, lint produces .ln files which store additional information than .ln files produced in basic mode. In enhanced mode, lint can read and understand all .ln files generated by either basic or enhanced lint modes. In basic mode, lint can read and understand .ln files generated only using basic lint mode.
By default, lint uses libraries from the /usr/lib directory. These libraries are in the basic lint format, that is, libraries shipped with C 3.0.1 and below. You can run a makefile once, and create enhanced lint libraries in a new format, which will enable enhanced lint to work more effectively. To run the makefile and create the new libraries, enter the command:
% cd /opt/SUNWspro/SC4.2/src/lintlib; makewhere /opt/SUNWspro/SC4.2 is the installation directory. After the makefile is run, lint will use the new libraries in enhanced mode, instead of the libraries in the /usr/lib directory.
The specified directory is searched before the standard place.
Two options to lint are particularly useful in developing a filter: