Please note: This chapter is not about how to include header files that may be in some directory other than the
current directory. For that information see the -i option (Section 4.4.2 Preprocessor ) or Section 18.2.1 INCLUDE
Environment Variable . This chapter explains how information in header files (and possibly modules) is
interpreted.
Examples of libraries are compiler libraries such as the standard I/O library, and third-party libraries such as windowing libraries, and database libraries. Also, an individual programmer may choose to organize a part of his own code into one or more libraries if it is to be used in more than one application. The important features of libraries, in so far as linting is concerned, are:
Therefore, to produce a full and complete analysis it is essential to know which headers represent libraries. It is also possible for modules to be available for linting but, because they are created beyond the control of the immediate programmer, they too can benefit from the designation ’library’.
By default code in library regions is not fully analyzed. See flag +flf for more information.
A library header file is a header file that describes (in whole or in part) the interface to a library.
The most familiar example of a library header file is stdio.h. Consider the file hello.c:
#include <stdio.h> int main(void) { printf( "hello world\n" ); }
Without the header file, PC-lint Plus would complain that printf was neither declared (Informational 718 ) nor
defined (Warning 526 ). (The distinction between a declaration and a definition is extremely important in C/C++. A
definition for a function, for example, uses curly braces and there can be only one of them for any given function.
Conversely, a declaration for a function ends with a semi-colon, is simply descriptive, and there can be more than
one).
If hello.c were a C++ program an even stronger message would be issued, but we will assume a straight C
program.
With the inclusion of stdio.h (assuming stdio.h contains a declaration for printf), PC-lint Plus will not issue
message 718 . Moreover, if stdio.h is recognized as a library header file, (it is by default because it was specified
with angle brackets), PC-lint Plus will understand that source code for printf is not necessarily available and will
not issue warning 526 either. Note: Other messages associated with library headers are not suppressed
automatically. But you may use -wlib or any of the -elib ... options for this purpose. See Section 4.3.1 Error
Inhibition .
A header file can become a library header file if:
You may determine whether header files are library header files by using some variation of the -vf verbosity option. For each included library header you will receive a message similar to:
Including file c:\compiler\stdio.h (library)
The tag: ’(library)’ indicates a library header file. Other header files will not have that tag.
What follows is a more complete description of the three options used to specify if or when a header file is a library
header file.
+libclass( identifier [, identifier] ...) specifies the set or sets of header files that are assumed to be
library header files.
Each identifier can be one of:
angle All headers specified with angle brackets.
foreign All header files found in directories that are on the search list (-i or INCLUDE as
appropriate).
Thus, if the #include contains a complete path name then the header file is not considered ’foreign’. To endow such a file with the library header property use either the +libh option or angle brackets. For example, if you have
#include "\include\graph.h"
and you want this header to be regarded as a library header use angle brackets as in:
#include <\include\graph.h>
or use the option:
+libh(\include\graph.h)
Similar remarks can be made about
#include "include\graph.h"
If a search list (specified with -i option or INCLUDE) is used to locate this file it is considered foreign;
otherwise it is not.
ansi The ’standard’ ANSI/ISO C header files, viz.
| assert.h | limits.h | stddef.h |
| ctype.h | locale.h | stdio.h |
| errno.h | math.h | stdlib.h |
| float.h | setjmp.h | string.h |
| fstream.h | signal.h | strstream.h |
| iostream.h | stdarg.h | time.h |
all All header files are regarded as being library headers.
By default, +libclass(angle,foreign) is in effect. This option is not cumulative. Any +libclass option
completely erases the effect of previous +libclass options. To specify no class use the option
+libclass().
+libdir(directory [, directory] ... ) activates
-libdir(directory [, directory]...) deactivates
the directory (or directories) specified. The notion of directory here is identical to that in the -i option. If a directory is activated then all header files found within the directory will be regarded as library header files (unless specifically inhibited by the -libh option). It overrides the +libclass option for that particular directory. For example:
+libclass() +libdir( c:\compiler ) +libh( os.h )
requests that no header files be regarded as library files except those coming from directory c:\compiler and the header os.h (see below). Also,
+libclass( foreign ) -libdir( headers )
requests that all headers coming from any foreign directory except the directory specified by headers should
be regarded as library headers.
Wild card characters ’*’ and ’?’ are supported. Note: A file specified as
#include "c:\compiler\i.h"
is not regarded as being a library header even though +libdir(c:\compiler) was specified. Only files found in c:\compiler via a search list (-i or INCLUDE) are so regarded and only when the -i option matches the libdir parameter. For example,
#include "compiler\i.h"
will also not be considered as library even though the -ic: option is given, and the file is found by searching.
The -i search directory (c:) is not matching the libdir directory (c:\compiler).
+libh( file[, file] ... ) adds
-libh( file[, file]...) removes
files from the set that would otherwise be determined from the +libclass and -/+libdir options. For example:
+libclass( ansi, angle ) +libh( windows.h, graphics.h ) +libh( os.h ) -libh( float.h )
requests that the header files described as ansi or angle (except for float.h) and the individual header files:
windows.h, graphics.h and os.h (even if not specified with angle brackets) will be taken to be library
header files.
Wild card characters ’*’ and ’?’ are supported.
For libh to have an effect, its argument must match the string between quotes or angle brackets in the #include line. Thus in the case of:
#include <../lib/graphics.h>
you must have +libh(../lib/graphics.h).
Note that the libh option is accumulative whereas the +libclass option overrides any previous +libclass
option including the default.
When a #include statement is encountered, the name that follows the #include is defined to be the
header-name (even if the name is a compound name containing directories). When an attempt is made to
open the file, a list of directories is consulted, which are all those specified by -i options and the INCLUDE
environment variable. The directory that is used to successfully open the file is defined to be the
header-directory.
The options +libdir (...) and -libdir (...) are applied to the header-directory and the options +libh (...) and -libh (...) are applied to the header-name (as defined in the previous paragraph). For example, given the following:
#include "graphics\shapes.h"
Suppose that the following option had been given:
-iC:\
and suppose further that a file "C:\graphics\shapes.h" exists. Then the header-name would be "graphics\shapes.h" and the header-directory would be "C:\". Any one of the following options could be used to designate the file as a library file.
+libh( graphics\* ) +libh( *shapes.h ) +libdir( C:* ) +libdir( C:\ )
You may designate that a module is a library module using the option:
+libm( module-name )
You would normally use just the ’+’ form of the option. But you may use -libm to undo the effects of a +libm
option with some arguments.
This option has the effect of designating the entire module and all of the header files that it includes, as "library".
That is, messages will be inhibited via -wlib or -elib ... options. Unused globals defined within such a module will
draw no complaints, etc.
As an example, suppose you have an application alpha.c, and that this code requires the services of a module beta.c, which is generated by a separate program. Typically the interface to beta.c will be described by a header file beta.h and a typical linting can be specified by:
lint +libh( beta.h ) alpha.c
But another possibility is to include beta.c in the lint. This would have the advantage of facilitating inter module value tracking. The typical command to do this would be:
lint +libh( beta.h ) +libm( beta.c ) alpha.c beta.c
Note that the option libm takes a pattern that may include wild-cards. Let us suppose that our generator will generate not just beta.c but a sequence of three modules
beta1.c beta2.c beta3.c
Then they can all be designated as library with the single option
+libm( beta*.c )
The pattern specified by the libm option must match the name of the module as provided for analysis. For example:
lint +libm( C:/directory/beta.c ) C:/directory/beta.c
Note that the option +libm(beta.c) would not be effective if the module name included the path.
In this section we deal with the case of assembly-language modules. For in-line assembly code see Section 4.12.4
In-line assembly code .
If one or more modules of your application are written in assembly language or, equivalently, in some language other than C or C++ (a common phrase is "mixed language"), you must arrange so that the missing code does not cause PC-lint Plus to give spurious messages. The most common way of proceeding is to create a header file describing the assembly language portion of your application. This header file, say asm.h, will have property (a) of library header files in that the objects declared therein will not be defined in files seen by PC-lint Plus. Hence we make it a library header file with the option:
+libh(asm.h)
Finally, the assembly language portion of your application may be the only portion of your application that is referencing, initializing or accessing some variable or function. A spurious "not referenced" or "not accessed" message would be given. The easiest thing to do is to explicitly suppress the message(s). For example, if the assembly language portion is the only portion accessing variable alpha and you are getting message 552, then place option -esym(552,alpha) among your lint options. If you are using our suggested setup, as described in Section 19.2 Recommended Setup , then std.lnt will now have the contents:
c.lnt options.lnt +libh(asm.h) -esym(552,alpha) //accessed in assembly language
You might be tempted to place these options in lint comments within asm.h. Unfortunately, the libh option will be
set too late to establish asm.h as a library header.
You might yet say that "My assembly language routines are sometimes opted out and sometimes opted in, and this
is under control of a global preprocessor variable USEASM. When opted out, C/C++ equivalent routines are activated.
How can I cope with this varying situation?"
This actually makes the situation easier. Just make sure that when you are linting, USEASM is opted out. You might use:
#ifdef _lint #undef USEASM #endif
or some equivalent sequence. In this way, lint will know the intent of the assembly code from the equivalent C/C++
code. The previously suggested options of +libh and -esym are then not necessary.