

























                     LLIINNTT RReeffeerreennccee MMaannuuaall




                               by

                         J. A. Gardner

                         Thinkage Ltd.
                       85 McIntyre Drive
                       Kitchener, Ontario
                        Canada  N2R 1H6



















                Copyright 1995 by Thinkage Ltd.



Thinkage Ltd.                          LINT Reference Manual






                     TTaabbllee ooff CCoonntteennttss


11.. IInnttrroodduuccttiioonn........................................................................................22

22.. LLIINNTT DDiirreeccttiivveess..................................................................................33

33.. LLIINNTT OOuuttppuutt..........................................................................................44
    Message Classes........................................4
    Output Grouping........................................6
    Type Information.......................................7

44.. LLIINNTT CCoonnvveennttiioonnss................................................................................99

55.. UUnnuusseedd DDeeffiinniittiioonnss aanndd DDeeccllaarraattiioonnss........................................1100
    Marking Symbols As Used...............................10

66.. UUnnddeeffiinneedd oorr UUnnddeeccllaarreedd DDaattaa OObbjjeeccttss......................................1111

77.. UUnnrreeaacchhaabbllee CCooddee..............................................................................1122
    Marking Unreachable Code..............................12

88.. FFuunnccttiioonn RReettuurrnn VVaalluueess..................................................................1133
    Ignoring Return Values................................14

99.. TTyyppee CChheecckkiinngg....................................................................................1155

1100.. FFuunnccttiioonn DDeeccllaarraattiioonnss..................................................................1177
    The #pragma varargs Directive.........................18
    The #pragma argsused Directive........................19

1111.. AAlltteerrnnaattee FFoorrmmss..............................................................................2211

1122.. MMiisscceellllaanneeoouuss NNootteess......................................................................2233

1133.. EExxttrraa CCoommppiilleerr WWaarrnniinnggss..............................................................2244
    Alignment Problems....................................24

1144.. TThhee LLIINNTT CCoommmmaanndd LLiinnee..................................................................2266
    Abbreviating Options:.................................30
    Other Ways to Use LINT................................30
    Summary Files.........................................30
    LINT Libraries........................................31
    Review of Inputs and Outputs..........................32
    Multiple Definitions..................................32
    Configuration Files...................................33





November, 1995                                        Page i



LINT Reference Manual                          Thinkage Ltd.






                         CChhaapptteerr 11
                        IInnttrroodduuccttiioonn

    LINT is  a program that examines C source code and makes
note of  "irregularities" in  the code.  When LINT was first
implemented, its  primary function  was  locating  bugs  and
inefficiencies.   However, as  the  C  programming  language
spread to  a variety  of  machines  and  systems,  LINT  was
enhanced to  locate deviations from the strict definition of
C.

    The ANSI  standard for  C now  provides  the  "official"
definition of  C.   However,  the  ANSI  standard  does  not
entirely describe the behavior of C implementations, because
the standard  allows certain operations to be performed in a
system-dependent  way.     If   a  program   is  written  in
conformance with  the ANSI  standard, avoiding  such system-
dependent features,  we say  that the  program is written in
_S_t_r_i_c_t_ _C.

    Ideally, all  programs should  be written  in Strict  C,
since these  programs are  maximally portable.   One  of the
major functions  of LINT  is to detect code constructs which
do not  conform with  Strict C.   Such  constructs are often
valid and  can be used in working programs, but they are not
truly portable  and may  be indications of loose programming
style.  LINT shows where you have written non-portable code;
for portability, you should try to remove such code.

    Before we  begin, we  should note  that it is inevitable
that LINT  will miss  some problems  and will  also complain
about code  that turns  out to be valid.  The designers have
tried to  chart a course between too much laxness (which may
miss significant  irregularities) and  too much  nit-picking
(which produces  quantities of  irrelevant output  that  you
will likely  ignore).  Thus we have designed this version of
LINT to  report situations that are _u_s_u_a_l_l_y signs of errors.
While odd  constructions and  unusual programming  style can
confuse LINT  from time  to time,  the majority  of material
that LINT locates should deserve the programmer's attention.











Page 2                                        November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 22
                      LLIINNTT DDiirreeccttiivveess

    LINT  understands   all  the   usual   C   preprocessing
directives (e.g.  ##iinncclluuddee,, ##ddeeffiinnee,,  etc.).   In  addition,
LINT recognizes  a number  of other directives that have the
same sort of format:

          #pragma aligned
          #pragma argsused
          #pragma notreached
          #pragma optresult
          #pragma used
          #pragma varargs

These directives  tell LINT  about special  features of your
source code  and  allow  LINT  to  provide  more  meaningful
diagnostic messages.   The  usage of  each LINT directive is
explained later in the manual.

    ANSI C  compilers should  not reject  these special LINT
directives; the  ANSI standard  says that  C  compilers  are
supposed to  ignore  any  ##pprraaggmmaa  directives  they  do  not
understand.     However,  non-ANSI  C  compilers  may  issue
diagnostic messages  for these  ##pprraaggmmaa directives, and even
some ANSI  C compilers may issue warnings about unrecognized
##pprraaggmmaas.



























November, 1995                                        Page 3



LINT Reference Manual                          Thinkage Ltd.



                         CChhaapptteerr 33
                        LLIINNTT OOuuttppuutt

    LINT generally  produces quite  a lot  of  output.    By
default the output is written to the terminal, but it can be
redirected to  a file  using the standard output redirection
constructions on the LINT command line.

    The first  lines of  output  from  LINT  are  diagnostic
messages comparable  to those  that might be produced by a C
compiler.  These diagnostics describe easily detected things
like syntax errors.

    Following this  comes output  that is  unique  to  LINT.
Most lines in the output have the form

          filename,lineno: class: text

where filename  is the  name of one of the source files that
LINT is  scanning and  lineno is  a line  number within that
file.   The class field tells the type of problem found; see
"Message Classes" below for more information.  The text part
of the  message  provides  specific  information  about  the
problem.

    Some lines may have the form

          libname: class: text

where libname  is the  name of  a LINT  Library.   For  more
information on  LINT libraries, see the last section of this
manual.


MMeessssaaggee CCllaasssseess

    Each message  produced by LINT is labelled with a string
indicating what  kind of problem the message describes.  The
following message classes are recognized:

Error:
     Same as  error messages  produced by the compiler: code
     so incorrect  that there is no way to generate any sort
     of object code.

Warning:
     Marks a  construct that is invalid but a compiler could
     still generate  some kind of object code.  For example,
     the ANSI  standard does  not allow  assignments between
     pointers of  different types,  but most  compilers  can




Page 4                                        November, 1995



Thinkage Ltd.                          LINT Reference Manual



     still  generate   sensible  object  code  for  such  an
     operation.

Unusual:
     Marks a  construct which  is valid,  but which  is  not
     often seen in C programs.  For example,

        i=i;

     is  valid  but  suspicious,  possibly  indicating  some
     problem in your code.

Note:
     Marks a  construct which  is invalid  but always  works
     properly on the current machine.  For example,

        printf("%ld",1);

     is invalid  since %ld requires a lloonngg argument but 1 is
     just iinntt.   However,  this  always  works  properly  on
     machines where lloonngg and iinntt are the same size.

MachDepd:
     Marks a  valid construct  whose  behavior  is  machine-
     dependent.   For  example,  the  result  of  (-7/2)  is
     machine-dependent, since  the ANSI standard allows this
     kind of  division to  truncate either  towards or  away
     from zero.

Extension:
     Marks a  construct that  is an  extension to  the  ANSI
     standard.

Efficiency:
     Marks code  that has  been written  in  a  particularly
     inefficient way, or using constructs that are likely to
     execute slowly.

NotMinimal:
     Marks a  construct which is valid ANSI C but may not be
     accepted by older C compilers (e.g. vvooiidd ** pointers).

Info:
     Provides cross-reference information while using LINT.

IntrnErr:
     An internal  error in LINT itself (for example, a table
     overflow).






November, 1995                                        Page 5



LINT Reference Manual                          Thinkage Ltd.




OOuuttppuutt GGrroouuppiinngg

    LINT output is grouped according to the functions of the
source code.

    The first  line of a group of messages gives the name of
a function or an external variable.  After that come all the
messages pertaining  to that  function  or  variable.    The
messages end  with a  blank line,  followed by  the group of
messages for the next function or variable.

    Groups are sorted in alphabetical order according to the
name of the function or variable.

    The first line of every function group gives the name of
the function  and  the  type  of  value  that  the  function
returns.   If LINT  has found a definition for the function,
the first line of the function group is

          Function "NAME" returns "TYPE".

where NAME  is the name of the function and TYPE is the type
of value that the function returns.

    If LINT  can't find  a definition for the function, LINT
looks at the first _r_e_f_e_r_e_n_c_e to the function that appears in
the source code and prints

          Function "NAME" is assumed to return "TYPE".

where TYPE  is the  type suggested  by the  way in which the
function is  used.   In keeping  with the  rules of  C, LINT
assumes that  a function  returns iinntt if the function is not
explicitly declared  to have a different type.  If the first
reference to  the function  does not use a return value from
the function, the message is

          Function "NAME" assumed to return no value.

    If LINT scans a function definition and finds that there
are no  rreettuurrnn statements  that return a value, LINT outputs
the message

          Function "NAME" returns no value.

You should distinguish between this message and

          Function "NAME" returns void.





Page 6                                        November, 1995



Thinkage Ltd.                          LINT Reference Manual



The vvooiidd  message appears  when  a  function  is  explicitly
declared with  the vvooiidd  keyword.   The "no  value"  message
appears when a function definition has no rreettuurrnn statements.

    The first  appearance of an external variable is treated
in much  the same way as the first appearance of a function.
You will see a message like

          External "NAME" is "TYPE".

or

          External "NAME" is assumed to be "TYPE".

    With one  exception, the  messages we  have described so
far are always issued, whether or not there are errors.  The
exception is  when  a  symbol  appears  in  a  LINT  library
(described later  on) and is not referenced in normal source
code.   Messages about  library functions and variables only
appear if the symbol is used in source code.

    Other messages  in LINT  output describe situations that
may be  errors.  These messages refer to difficulties within
the function with which they are grouped.


TTyyppee IInnffoorrmmaattiioonn

    At the  end of  its output,  LINT displays  a  block  of
information describing  the types of the program.  A typical
line of output is

          filename,lineno: type

where filename  is the  name of  the file where the type was
defined and  lineno is  the line number where the definition
began.

    LINT provides information about any ttyyppeeddeeffs, enumerated
types, structures,  and/or unions  that were involved in the
messages produced.   This lets you locate the definitions of
these types.

    If a  type appears  twice in this list, it usually means
that there is more than one definition for the same type and
the types are not assignment-compatible.

    LINT also  checks for  structures and  unions which  are
used in  functions and which have been incompletely defined.
Incomplete definitions  are acceptable as long as there is a
complete definition  somewhere.   All  complete  definitions



November, 1995                                        Page 7



LINT Reference Manual                          Thinkage Ltd.



have to be identical.  If complete definitions conflict with
each other, LINT issues a diagnostic beginning with

          filename : type

where filename is the name of a file where the type was used
and found to conflict with another definition.















































Page 8                                        November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 44
                      LLIINNTT CCoonnvveennttiioonnss

    A function  is  _d_e_f_i_n_e_d  by  the  function  header  that
actually starts  the function.  This tells the type of value
that the function returns and describes the arguments of the
function.   An external variable is _d_e_f_i_n_e_d by a declaration
for the  variable that is outside the scope of all functions
and that does not include the keyword eexxtteerrnn.

    A function is _d_e_c_l_a_r_e_d by a declaration or function call
inside another  function.   An external variable is _d_e_c_l_a_r_e_d
by a  declaration that  includes the keyword eexxtteerrnn.  Such a
variable  declaration   does  not  allocate  space  for  the
variable; it  merely describes  the type of the variable and
presumes that the variable is defined elsewhere.

    A variable  is _s_e_t  if it  is assigned  a value  or if a
pointer to  the variable is taken.  Similarly, a variable is
_u_s_e_d if  its value  is used  or if a pointer is taken.  (You
might wonder  why taking  a pointer marks a variable as both
"set" and  "used".   The answer  is that once a pointer to a
variable is  taken, LINT  can't keep track of assignments or
uses of  the variable through the pointer.  Once the pointer
is taken, LINT can only assume that the data object may have
been both set and used.)




























November, 1995                                        Page 9



LINT Reference Manual                          Thinkage Ltd.



                         CChhaapptteerr 55
            UUnnuusseedd DDeeffiinniittiioonnss aanndd DDeeccllaarraattiioonnss

    One of  the easiest  problems for  LINT  to  find  is  a
variable or  function that is defined but not used or called
in the  rest of  the program.   Such  items can  usually  be
deleted, since  they are  not performing any function in the
program.   The diagnostic  messages for  such situations are
listed and explained below.

Function "NAME" is never called.
     The given  function was  defined in the source code but
     never called.

External "NAME" is never used.
     The given external variable was defined but never used.

External "NAME" is defined but never set or used.
     This is essentially the same as the previous message.

External "NAME" is set but never used.
     The given  external variable  was assigned a value, but
     then was never used for anything.

Messages are  _n_o_t generated if a symbol in a LINT library is
unused.


MMaarrkkiinngg SSyymmbboollss AAss UUsseedd

    Sometimes, you  may  intentionally  declare  a  variable
without using  it.   For example, suppose a variable is only
used inside  a ##iiff  block and  that block  of  code  is  not
compiled because  the ##iiff  condition is not met.  LINT would
normally issue  an error message for this condition, but you
might not consider this situation an error.

    To avoid  this sort  of message,  you can  add the  LINT
directive

          #pragma used NAME NAME NAME ...

to your  source code.  This tells LINT that the names listed
in the  directive are  used by  your  program,  even  if  it
doesn't look like they are.









Page 10                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 66
            UUnnddeeffiinneedd oorr UUnnddeeccllaarreedd DDaattaa OObbjjeeccttss

    LINT uses  a simple-minded  way  to  find  places  where
undefined variables  are used:  a variable  is assumed to be
undefined if  a statement  using the variable appears in the
code before  the variable is set.  Of course, it is possible
to construct  programs where  this approach fails.  With the
use of  spaghetti-like ggoottoos,  the top-down technique can be
outwitted.

    Because static  and external variables are automatically
initialized  to  zero  by  the  compiler  if  they  are  not
initialized explicitly,  LINT does not pick up problems with
these variables.

    The following  diagnostics pertain  to data objects that
are used before they are set, defined, or declared.

Function "NAME" is called but never defined.
     The source  code contains a call to the given function,
     but the function is not defined anywhere in the code.

"NAME" is set but never defined.
     The given  variable has  been assigned  a value,  but a
     proper definition does not appear in the source code.

"NAME" is used but never defined.
     The value  of the  given variable  was  used,  but  the
     variable was never defined.

"NAME" is used but never defined or set.
     The value  of the given variable has been used, but the
     variable was neither defined nor set.

"NAME" is defined and used but never set.
     The given  variable is defined and used, but never set.
     This message  is only issued for local variables, since
     all external variables are automatically initialized to
     zero (if no explicit initialization is specified).














November, 1995                                       Page 11



LINT Reference Manual                          Thinkage Ltd.



                         CChhaapptteerr 77
                      UUnnrreeaacchhaabbllee CCooddee

    LINT attempts  to detect  parts of  the source code that
cannot  be   reached  (for  example,  unlabelled  statements
following a  ggoottoo).  It also attempts to find loops that can
never be exited from the bottom, such as wwhhiillee((11))......  At the
same time,  LINT finds loops that cannot be entered from the
top.

    The message that is issued for detected unreachable code
is

          Non reachable code at "TEXT".

where TEXT is the source code that cannot be reached.


MMaarrkkiinngg UUnnrreeaacchhaabbllee CCooddee

    LINT cannot  detect functions which are called and never
return (for  example,  ones  that  terminate  execution  via
exit).  This means that it is possible for LINT to miss some
unreachable code, as in

          g()
          {
              exit(-1);
          }
          f()
          {
              ...
              g();
              /* everything that follows
               * is unreachable */
              ...
          }

    To mark  this kind  of situation,  you can  use the LINT
directive

          #pragma notreached

When this  directive  appears  in  your  source  code,  LINT
regards  any   source  code   following  the   directive  as
unreachable, up  to  the  end  of  the  block  or  the  next
statement label.   Appropriate  diagnostic messages  will be
issued.






Page 12                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 88
                   FFuunnccttiioonn RReettuurrnn VVaalluueess

    LINT reports functions that contain both

          return( expression );

and

          return;

This kind  of situation usually results in errors (since the
calling function  may assume  a value  is being returned but
one of the rreettuurrnn statements does not return a value).

    Correspondingly, LINT  makes note  of whether  or not  a
call to  a function  makes use  of a  return value  from the
function.   If the  caller expects  a value but the function
does not  return one,  it is clearly a bug.  If the function
returns a value but the the caller does not use it, it could
be an error, an inefficiency, or sloppy programming style.

    If a  function definition  contains no rreettuurrnn statements
that return  a value,  LINT regards the function type as iinntt
unless it is explicitly declared differently.  If LINT finds
a reference  to the  function before  it finds  the function
definition, it  assumes that  the function  returns a  value
unless  the   function  is   explicitly  declared  as  vvooiidd.
Programmers who  are used  to looser controls than this will
find themselves with a large number of diagnostic messages.

    The messages  related  to  function  return  values  are
listed below.

Value is used but none returned.
     A function  did not  return a  value, but the statement
     that called  the function  behaved as  if a  value  was
     returned.

Function NAME has no return value
     A function  was  defined  as  returning  a  value  (the
     function is not vvooiidd)) but it did not contain a

        return(expression)

     statement.

Return value ignored.
     The given function contains a





November, 1995                                       Page 13



LINT Reference Manual                          Thinkage Ltd.



        return(expression);

     statement, but the caller never uses the return result.

Return value sometimes ignored.
     This is  similar to the last situation, except that the
     return result is sometimes used, sometimes not.


IIggnnoorriinngg RReettuurrnn VVaalluueess

    There is always the possibility that you want to write a
function whose  return value  can be ignored.  The C library
has several  functions whose  return value  is  superfluous.
For example,

          strcpy(A,B)

copies string  B into  string A  and returns a pointer to A.
This is  unnecessary, since the caller already has a pointer
to A.

    LINT lets you mark functions with optional return values
by using  a directive  similar to  the ##directives  of the C
preprocessor.

          #pragma optresult

can  be  placed  immediately  before  the  definition  of  a
function  that  returns  an  optional  result.    LINT  then
recognizes that  this function  returns a result that can be
ignored; LINT  does not give error messages if the result is
ignored.





















Page 14                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 99
                       TTyyppee CChheecckkiinngg

    LINT enforces stronger type-checking than most compilers
do.   In expressions  where  different  types  of  data  are
intermixed,  LINT   observes  the   strict  conventions  for
conversions of  data and  requires that  everything else  be
properly cast.

    LINT checks for type incompatibilities in three places:

 (a) in the arguments passed to functions
 (b) in the return values received by functions
 (c) in structure manipulations

For fullest  type-checking, the  code should  use prototypes
wherever possible.  LINT also checks for situations in which
some function  calls take  place with  a prototype  in scope
while others do not.

    When arguments  are passed  to functions,  LINT issues a
diagnostic if the argument type passed by the caller differs
from the  argument type  expected by  the  called  function.
Similarly, LINT  complains if  the argument type returned by
the called  function differs from the argument type expected
by the  caller.  The messages associated with this situation
are given below.

Argument N is "TYPE1", but declared as "TYPE2".
     When the given function was called, the caller passed a
     value of  type TYPE1  for argument  number N,  but  the
     called  function  expected  a  value  of  TYPE2.    For
     example, you might see

        Argument 2 is "int", declared "unsigned int".

     This indicates  that the caller passed an integer value
     as the  second argument of the function, but the called
     function expected an unsigned integer.

Argument N is "TYPE", but declared as a different "TYPE"
     This is  an odd  situation where  the definition  and a
     declaration give  the argument different types, but the
     strings used to print out TYPE turn out to be the same.
     For example, suppose that a function has a local ssttrruucctt
     X, but  there is also an external ssttrruucctt X which is not
     compatible  with   the  local  one.    If  the  program
     invalidly tries to combine external and local variables
     of type  X, you  get the above message; even though the
     types have the same name, they are different.  The same




November, 1995                                       Page 15



LINT Reference Manual                          Thinkage Ltd.



     sort of  situation may  happen with  other  LINT  error
     messages.

"NAME" is redeclared as function type "TYPE".
     When NAME  was first  declared, it was said to return a
     value of  one type.  Now NAME has been declared or used
     as a function returning a different type of value.

"NAME" declared as returning "TYPE"
     The function NAME has been declared as returning a TYPE
     that is different than its definition.

"NAME" declared as "TYPE"
     The variable NAME has been declared with a TYPE that is
     different than its definition.

"NAME" is redefined as function.
     NAME was  originally declared as a variable, but is now
     being defined as a function.

    LINT also  issues a  message whenever  a data  object is
implicitly shortened.  For example, suppose we have

          long l;
          int i;
            /* stuff */
          i = l;

    The C  compiler automatically  shortens the long "l" and
assigns the  result to  "i".   However, LINT flags this as a
potential  problem   (since  different   integer  sizes   on
different machines  may affect  how this  works).   No error
message is  issued if  the conversion is done explicitly, as
in

          i = (int) l;

    As a  final note  about type-checking, LINT occasionally
gets some  complicated types  wrong.   For example, warnings
about structures  that contain  arrays of  structures do not
give the  right type  (namely ssttrruucctt).    The  same  problem
occurs when  LINT is  not given  the internal structure of a
ssttrruucctt.   For example,  it is  valid for  a source module to
declare

          struct ABC *ptr;

without describing the internal structure of the ABC ssttrruucctt.
In such  cases, LINT  does not  have enough  information  to
determine if  code is valid, so the warning messages may not
be entirely accurate.



Page 16                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 1100
                   FFuunnccttiioonn DDeeccllaarraattiioonnss

    LINT compares  all the  available prototype declarations
for a  function to  make  sure  that  the  prototypes  match
_e_x_a_c_t_l_y.   For example,  LINT  notes  situations  where  one
prototype gives  vvooiidd **  as the  type of  an argument  while
another types  the same  argument as  cchhaarr **.   In practice,
there is  no difference  between these  two  pointer  types;
however, LINT  makes note of the situation because it may be
indicative of an error.

    In addition to checking that the argument types expected
by a  called function match the argument types passed by the
caller, LINT  also  checks  that  the  _n_u_m_b_e_r  of  arguments
expected by  the  called  function  matches  the  number  of
arguments passed  by the caller.  If there is a mismatch, it
prints

          Called with N arguments, requires M

where N  is the  number of  arguments that the caller passes
and M is the number of arguments that the function expects.

    Whenever possible,  LINT checks  to  see  that  argument
declarations in  function prototypes  agree exactly with the
declarations  in   the  function   definition.      If   the
declarations do not agree, LINT outputs

          Prototype argument N is "TYPE" but declared as
          "TYPE"

LINT expects  argument declarations  to match  exactly.  For
example, the vvooiidd ** type is considered assignment-compatible
with all pointer types and therefore there is not a conflict
between vvooiidd ** and another pointer type.  Nevertheless, LINT
points out  the difference,  simply to  warn you  that there
seems to be a discrepancy in your code.

    Finally, LINT makes sure that the number of arguments in
a prototype  declaration matches  the number in the function
definition.  If not, LINT prints

          Prototyped with N arguments, but requires M

where M and N are both integers.








November, 1995                                       Page 17



LINT Reference Manual                          Thinkage Ltd.




TThhee ##pprraaggmmaa vvaarraarrggss DDiirreeccttiivvee

    In earlier  versions of  C it  was valid  to  pass  more
arguments than  the function definition specifies or to pass
fewer arguments.  This is not valid in ANSI C unless you use
the "..."  construct in  the prototype;  however, older code
may still  make use  of  such  calling  sequences  and  most
compilers still handle the situation properly.

    In  order  to  handle  all  the  possibilities  of  this
situation, LINT  introduces the  ##pprraaggmmaa vvaarraarrggss  directive.
The directive has two forms.

          #pragma varargs N

indicates that  the next  function to  be defined can take a
variable number  of arguments  but must  have a minimum of N
arguments.  For example, we might write

          #pragma varargs 3
          int Mini(N,a,b,c,d);
          int N,a,b,c,d;
          { ....

to declare  a function  Mini that  must take  at least three
arguments and  can have  more.   In this case, LINT does not
issue an  error message  if you  have at least three integer
arguments present.

    With this  form of  the ##pprraaggmmaa  vvaarraarrggss directive, LINT
typechecks all the arguments that are present.  In the above
example, LINT  ensures that  all the  arguments being passed
are integers.

    The second form of the directive is

          #pragma varargs N M

where both  N and  M are  integers.  This indicates that the
next function  to be  defined  must  have  a  minimum  of  N
arguments, and  LINT should  typecheck up  to M arguments if
they appear.   For  example, you  can imagine  a printf-like
function that  takes a format string plus one or more values
to print.  This could be preceded with

          #pragma varargs 2 1

showing that  the function must always have two arguments (a
format string  and at  least one output value) but that only




Page 18                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



the first  argument should  be typechecked (since the output
value(s) need not have a fixed type).

    The directive can also take the form

          #pragma varargs printf
          #pragma varargs scanf

These forms  may be  used to  indicate functions  that  take
format strings comparable to the strings of printf and scanf
(respectively).   LINT  compares  the  placeholders  in  the
format string  to the types of the arguments that follow the
format string, and reports any conflicts between types.  For
example, it  tells you if the argument corresponding to a %s
placeholder is an iinntt value (incompatible with %s).


TThhee ##pprraaggmmaa aarrggssuusseedd DDiirreeccttiivvee

    Some functions  are able  to use  all the arguments they
are passed  without actually  referring to every argument by
name.   For example,  consider a  function Max10  which  can
accept up  to 10  iinntt arguments  and return the value of the
largest argument.   The first argument passed to Max10 tells
how many  values have  actually been  passed.  This could be
defined with

          int Max10(N,a,b,c,d,e,f,g,h,i)
          int N,a,b,c,d,e,f,g,h,i;
          {
              int j,m,*p;
              m = a;
              p = &a;
              for (j=1; j < N; ++j)
                  if (p[j] > m) m = p[j];
              return(m);
          }

As  you  can  see,  the  function  does  not  refer  to  the
parameters b,  c, etc.  by name.   However,  it does look at
their values, since it walks through the stack using offsets
from a.  Therefore the values are used.

    This sort  of coding practice is a violation of the ANSI
standard.   The standard  doesn't let  you use subscripts to
access memory  locations outside  the  bounds  of  a  single
object, so  p[j] is  invalid if j is not zero.  On the other
hand, many  compilers still  accept code like this and older
programs may use it.





November, 1995                                       Page 19



LINT Reference Manual                          Thinkage Ltd.



    For  such   programs,  you  can  avoid  some  diagnostic
messages from LINT by putting the LINT directive

          #pragma argsused

on a line preceding the function, as in

          #pragma argsused
          int Max10(N,a,b,c,d,e,f,g,h,i)
             ...

This tells  LINT that  the function  uses all its arguments,
even if it doesn't appear to.









































Page 20                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 1111
                      AAlltteerrnnaattee FFoorrmmss

    For compatibility  with the  Bell Labs' version of LINT,
this version  of LINT may accept some directives in the form
of  comments.     These   are   only   recognized   if   the
+ControlComments option  is specified  on the  LINT  command
line.

          /*VARARGSN*/

(where N is an integer) is automatically converted to

          #pragma varargs 0 N

For example,

          /*VARARGS3*/

is equivalent to

          #pragma varargs 0 3

In addition,

          /*VARARGS*/

(with no value N) is equivalent to

          #pragma varargs 0

    In addition to VARARGS, the comment

          /*ARGSUSED*/

is automatically converted to

          #pragma argsused

and the comment

          /*NOTREACHED*/

is equivalent to

          #pragma notreached

    In all  cases, the  comment form  may not  contain white
space  (blanks,   tabs,  or   new-lines).    All  alphabetic
characters must  be in  upper case  and there can be nothing




November, 1995                                       Page 21



LINT Reference Manual                          Thinkage Ltd.



else in  the comment  except the keyword and any number that
should follow.




















































Page 22                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



                         CChhaapptteerr 1122
                    MMiisscceellllaanneeoouuss NNootteess

    LINT  always   uses  the  full  name  of  functions  and
variables, and  always distinguishes between upper and lower
case letters.  This is the way that C compilers are supposed
to work  as  well.    However,  some  compilers  or  loaders
truncate long  names to  a certain number of characters, and
some compilers  or loaders  do not  distinguish between  the
case of  letters in names.  For this reason, LINT issues the
following warnings.

NAME1 and NAME2 not unique in first N caseless characters.
     N is  the number  of characters  to which  names may be
     truncated to meet loader requirements.

NAME1 and NAME2 not unique without case distinction.
     This applies  to names  like VAR,  var, and Var used in
     the same program.

    LINT detects  redeclaration of  functions and  variables
defined outside  the scope  of any  function.   The  set  of
messages dedicated to this kind of problem are given below.

NAME redeclared.
     A given  variable has  been  invalidly  declared  in  a
     second place.

NAME retyped as "TYPE".
     A given  variable has  been used  as if  it had  a type
     different from its declared type.

NAME redeclared with type "TYPE".
     The given  variable appears in a new declaration with a
     different type than it previously had.

NAME is redefined as function.
     A  name  that  was  previously  given  to  an  external
     variable has now been given to a function.

    LINT assumes  that sshhoorrtt  integers have  a length  of 16
bits and  that lloonngg  integers have  a  length  of  32  bits,
regardless of  what length  these data  types have  on  your
machine.   The reason  is that  short and  long integers are
guaranteed to  have at  least these lengths on all machines.
Your hardware  may allow  longer integers  (for example,  36
bits) but  code that uses the increased size is not portable
to machines  with smaller  words.  For the same reason, LINT
assumes that  all characters  are 8-bit  signed  quantities,
even though they may be longer or unsigned on your machine.




November, 1995                                       Page 23



LINT Reference Manual                          Thinkage Ltd.



                         CChhaapptteerr 1133
                  EExxttrraa CCoommppiilleerr WWaarrnniinnggss

    In addition  to the  diagnostics produced especially for
LINT, the  LINT output  also  contains  all  the  error  and
warning messages  produced by  the parsing  phase of  the  C
compiler.  Most of these are self-explanatory, but there are
a few that deserve further comment.

Constant "CONSTANT" too large for "TYPE".
     As noted  earlier, LINT  assumes short  integers are 16
     bits  long   and  long   integers  are  32  bits  long.
     Therefore you may get this message, even though a short
     or long  integer type  on your machine is actually long
     enough to hold a given constant.

Character constant with no characters.
     Some compilers do not accept a null character constant.
     Your compiler may accept such constants, but LINT still
     complains about the construct.

Constant valued logical expression.
     This refers to situations like

        while (1) { ... }


AAlliiggnnmmeenntt PPrroobblleemmss

    In addition  to the error messages listed above, you may
receive the warning

          Possible alignment problems with cast

    When casting  data of  one  type  to  data  of  another,
alignment problems  may occur.   For  example, there  may be
difficulties in  casting a  character pointer  to an integer
pointer if  the character  pointer is  not aimed  at a  word
boundary.   At times,  however, you  may have taken pains to
make sure  that this  kind of  alignment  problem  will  not
occur.   In particular, you may have created a function that
returns a  value or pointer that is suitably aligned for any
use.   This is true of functions like malloc; the value that
malloc returns  is officially  a vvooiidd  ** pointer,  but it is
suitably aligned to store any sort of data.

    If you  have a  function that returns a suitably aligned
pointer, you can tell LINT by placing

          #pragma aligned




Page 24                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



in front  of the  start of  the function  declaration.  This
tells LINT that the function itself deals with any alignment
problems.



















































November, 1995                                       Page 25



LINT Reference Manual                          Thinkage Ltd.



                         CChhaapptteerr 1144
                   TThhee LLIINNTT CCoommmmaanndd LLiinnee

_S_y_n_t_a_x_:
          tlint [file] [option]*

          (+|-)ControlComments (-)  (+|-)Declarations (-)
          (+|-)Keep (-)             (+|-)StandardLibrary (+)
          (+|-)Verbose (-)          (+|-)Wide (-)
          Configuration=file        CrossReference=keyword
          Define=name=value         Include=directory
          INSTallation=file         Library=lib
          libraryName=string        Output=file
          Output+=file              StandardInclude=directory
          StandardLibrary=name      Summary=file
          Target=keyword            indeX=file

_E_x_a_m_p_l_e_s_:
          tlint myfile
          tlint x=files o=incls ln=proj def=PROJECT=1

_O_p_t_i_o_n_s_:
file
     is a  source file containing C code.  The other options
     on the  command line  determine whether LINT scans this
     file for  problem spots,  or uses  the file to create a
     summary or an entry in a LINT library.

indeX=file
     gives the  name of a text file.  Each line in this text
     file should  contain the  name of  one C  source  file.
     LINT checks  each of  these source  files individually.
     In addition  to a  source file name, a line in an index
     file  may   specify  ControlComments,   Configuration=,
     Include= and Define= options.  These options only apply
     to the  source file  named  on  the  same  line.    For
     example, if the line

        myfile define=VERSION=1

     appeared in  an index  file, LINT  would use  the given
     option when  examining myfile  but not  for other files
     named in  the index  file.   When processing  an  index
     line, LINT  normally uses  all the options appearing on
     the  main   command  line,   followed  by  the  options
     specified on  the index  line.    As  a  special  case,
     however, Include=  options on  a line  in an index file
     are used  before  any  Include=  options  on  the  LINT
     command line.  Only one indeX= option may appear on the
     command line.




Page 26                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



Configuration=file
     specifies a  configuration file  for LINT.    For  more
     information on configuration files, see below.

+ControlComments
     indicates that control comments of the type

        /*VARARGS*/

     should be  processed.  The default is -ControlComments,
     in  which   case  such   comments  are   ignored.     A
     ControlComments option  on a  line  in  an  index  file
     overrides any  ControlComments option  on the main LINT
     command line.

CrossReference=keyword
     indicates that  LINT output  should  include  a  cross-
     reference table  that shows  where symbols are defined,
     referenced,  set,   and  used.   (By  default,   cross-
     references are  not provided.)  Possible values for the
     keyword are:

     All - cross-references all symbols;

     External - only cross-references external symbols.

+Declarations
     may be  used when  creating a  LINT library  or summary
     file.   With this  option, LINT treats every file scope
     declaration  as   if  it  were  a  definition  for  the
     variable, instead of a simple reference.

Define=name=value
     has the same effect as

        #define name value

     in the C source code.  The option indicates that "name"
     should be  replaced with  "value" (as text) wherever it
     appears in  the source code being examined.  If "value"
     contains  blanks   or  tab  characters,  it  should  be
     enclosed in double or single quotes.

Include=directory
     is the  same as the Include= option for the C compiler.
     When LINT tries to find quoted include files, as in

        #include "file"

     it begins  by searching  the given  directory  for  the
     file.   If the  file is  not found there, LINT searches



November, 1995                                       Page 27



LINT Reference Manual                          Thinkage Ltd.



     any directory  named in  StandardInclude= options,  and
     finally searches the directory that contains the source
     file being  examined.   Any number  of Include= options
     may be  specified.   Directories are  searched  in  the
     order given on the command line.

INSTallation=file
     tells LINT  where to  find the  installation file.  The
     installation  file   tells   where   various   software
     components have  been installed.  For more information,
     see the section on _I_n_s_t_a_l_l_a_t_i_o_n_ _F_i_l_e_s below.

     If you  do not  specify an  INSTallation= option on the
     command line,  LINT checks  for an environment variable
     named LINT_INST  and uses  its value as the name of the
     installation file.   If  this environment variable does
     not exist, LINT uses the default installation file.

+Keep
     does  not   delete  intermediate   files  left  by  the
     preprocessor and the LINT steps.

Library=lib
     names a  LINT library that should be used when checking
     source code.  Any number of Library= options may appear
     on the  command line.   By  default, LINT automatically
     includes LINT  libraries of  standard C functions (e.g.
     printf) so that such functions are always recognized.

libraryName=string
     is used  when creating  a LINT  library.  See below for
     more details.

Output=file
     is used  when creating  a LINT  library or summary file
     (see below).   The output overwrites the file's current
     contents.

Output+=file
     is the  same as  Output=file,  except  that  output  is
     written to  the end  of the  current  contents  of  the
     specified file,  rather than  overwriting what the file
     already holds.

StandardInclude=directory
     is the  same as  the StandardInclude=  option for the C
     compiler.   When LINT tries to find include files whose
     names are enclosed in angle brackets, as in

        #include <file>




Page 28                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



     it begins  by searching  the given  directory  for  the
     file.   If the  file is  not found there, LINT searches
     directories named  in  Include=  options,  and  finally
     searches the  directory that  contains the  source file
     being examined.  Any number of StandardInclude= options
     may be  specified.   Directories are  searched  in  the
     order given on the command line.

StandardLibrary=name
     asks LINT  to include the standard library indicated by
     "name". The following names are recognized:

     C  -   the  standard   C  library.   This  is  included
     automatically, unless -StandardLibrary is specified.

-StandardLibrary
     does not include the standard C library routines.

Summary=file
     states that  the given  file is  a  summary  file  that
     should be  used as  input to  the LINT  operation.  See
     below for more on summary files.

Target=keyword
     controls the  kind of  problem-checking you want to do.
     The following keywords are recognized.

     Host -  describes any  problems that  may arise  if the
     program is  run on  the host  machine (i.e. the machine
     where you are running LINT).  This is the default.

     Extensions -  points out any extensions to C that might
     have been  used, as well as any machine-dependencies in
     the code.  It also describes the problems detected with
     Target=Host.

     Minimal -  points  out  any  features  that  may  cause
     problems  if  you  port  this  program  to  a  non-ANSI
     compiler.   This will  make note  of all  ANSI features
     used.   It also  describes the  problems detected  with
     Target=Extensions.

+Verbose
     prints out  the name  of the  file being examined.  The
     default is -Verbose.

+Wide
     prints output  in a  format that  is 132  columns wide.
     The default  is -Wide,  which prints  in  an  80-column
     format.




November, 1995                                       Page 29



LINT Reference Manual                          Thinkage Ltd.




_A_b_b_r_e_v_i_a_t_i_n_g_ _O_p_t_i_o_n_s_:

    The option  keywords given  above can  be abbreviated by
omitting any or all of the letters shown in lower case.  For
example, CrossReference=All may be abbreviated to

          crossref=all
          cref=all
          cr=all
          cr=a

and so  on.   When entering  option keywords,  you may  type
letters in upper, lower, or mixed case; the use of upper and
lower case  in this  documentation is  simply to  show  what
letters are and aren't required.


_O_t_h_e_r_ _W_a_y_s_ _t_o_ _U_s_e_ _L_I_N_T

    In addition  to checking C code for irregularities, LINT
can:

(a)  Extract a  summary file of information that can be used
     in other LINT operations.

(b)  Create a LINT library.

Summary files and LINT libraries are discussed below.


_S_u_m_m_a_r_y_ _F_i_l_e_s

    A summary file contains a "summary" of your source code:
the names  and types  of  all  the  external  variables  and
functions defined  or referenced in the code, plus any other
information LINT  may need  when checking  the code (such as
the declared  types of  function parameters).  Summary files
also record any error messages that might be issued by the C
compiler  when  parsing  the  source  code.    All  of  this
information is  stored in  a  special  format  that  is  not
directly readable by humans.

    To create a summary file from a normal source code file,
use the Output=file option, as in

          tlint src1.c output=summ

You can  add more  material to  the same  summary file using
Output+=file, as in




Page 30                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual



          tlint src2.c output+=summ

This appends  new material  to the  existing contents of the
summary file.

    When LINT  creates a  Summary file, LINT only summarizes
your source  code and checks for syntax errors.  It does not
check for  such problems  as non-portable constructs or type
mismatches.   However, you  can run  a summary  file through
LINT again to do standard type-checking.  For example,

          tlint srcfile output=lf
          tlint summ=lf

creates a  summary file,  then uses  the information  in the
summary file  to see if types match in symbol references and
definitions.

    The reason for creating summary files is the same as the
reason for  breaking up the source code of your program into
several source  files: it is easier to deal with source code
in small pieces than in one big hunk.  Some users may keep a
summary file  for every  source file.   If  the code  in one
source file  is changed,  you can create a summary file from
that source  file, then  run all  the summary  files of  the
program through  LINT to  see if  the change  has caused any
problems.   This is  much faster  than using LINT on all the
raw source code.


_L_I_N_T_ _L_i_b_r_a_r_i_e_s

    A LINT  library is similar to a summary file, in that it
contains  a  summary  of  C  source  code.    However,  LINT
libraries are  intended to  parallel  the  way  that  object
libraries work.

    To create  a LINT  library,  specify  both  the  Output=
option and the libraryName= option on the LINT command line.
For example,

          tlint file output=mylib libname="abc"

creates a  LINT library  named abc  in the  file mylib. This
name is  used in LINT diagnostic messages related to symbols
found in  the LINT  library.   Using LINT  in this  way only
generates minimal  messages; full  messages are printed when
you actually use the LINT library.

    To use  a LINT  library, specify  the Library= option on
the LINT command line, as in



November, 1995                                       Page 31



LINT Reference Manual                          Thinkage Ltd.




          tlint myfile library=mylib

When LINT  finds that  myfile contains  a  reference  to  an
undefined symbol,  LINT checks  the information in the given
LINT library  to see  if the  symbol is defined there.  This
works just  like compiling  a module  while referring  to an
object library.   No  error occurs  if a  symbol in the LINT
library has  the same  name as  a symbol in the source file;
the source file symbol is the one that is used.

    Functions should  only be  placed in a LINT library when
you are sure they contain no errors.  LINT does not look for
errors when it is creating a LINT library.


_R_e_v_i_e_w_ _o_f_ _I_n_p_u_t_s_ _a_n_d_ _O_u_t_p_u_t_s

    To specify  a file  as an  input, simply give the file's
name.  To specify a summary file as input, use Summary=file.
To specify  a LINT library as input, use Library=file.  LINT
uses all of the contents of a source file or a summary file;
it only  uses library  entries if  they  are  referenced  by
source code or a summary file.

    An index  file contains partial command lines to be used
by LINT  in its  operations.   These command  lines can name
source files  as  input,  but  not  summary  files  or  LINT
libraries.

    When  both   an  Output=  and  libraryName=  option  are
specified, LINT  creates a LINT library.  If only Output= is
specified, LINT  creates a  summary file.  If Output= is not
specified, LINT  examines a  source file or summary file for
problem spots  and writes  its diagnostics  to the  standard
output.


_M_u_l_t_i_p_l_e_ _D_e_f_i_n_i_t_i_o_n_s

    If LINT  finds two  definitions for the same function or
external variable,  it always  outputs a diagnostic message.
If the  two definitions are both in normal source code, LINT
arbitrarily chooses  the first  definition it  finds as  the
"correct" definition,  and issues  diagnostics for any later
deviations  from  this  definition.    If  one  of  the  two
definitions is  in a LINT library and the other is in normal
source code,  LINT chooses  the non-library  version as  the
"correct" definition.   In  this way, a definition in normal
source code overrides a library definition.




Page 32                                       November, 1995



Thinkage Ltd.                          LINT Reference Manual




_C_o_n_f_i_g_u_r_a_t_i_o_n_ _F_i_l_e_s

    A configuration  file consists of a series of directives
that control  the behavior of LINT.  The possible directives
are explained below.

define name string
     has the  same format and purpose as a ##ddeeffiinnee directive
     in normal  C code.  It creates a manifest or macro with
     the given value.

inline includefile
     lets you  simulate an include file.  When LINT finds an
     inline directive,  it begins  to gather  input lines up
     until  the   first  line   consisting  of  only  a  '#'
     character.  For example, in

        inline sim.h
        extern int junk1;
        extern int junk2;
        #

     LINT collects  the two declarations and associates them
     with the  name "sim.h".   If  a  program  contains  the
     directive,

        #include <sim.h>

     LINT takes  the gathered  text and  includes it at that
     point in  the program,  as  if  it  had  come  from  an
     included file.

map includename1 includename2
     says that all references of the form

        #include includename1

     should be converted to

        #include includename2

null includefile
     tells LINT  to  ignore  all  #include  directives  that
     attempt to include the specified file.

search pathname
     is equivalent  to Include=pathname  on the LINT command
     line.





November, 1995                                       Page 33



LINT Reference Manual                          Thinkage Ltd.



system_search pathname
     is equivalent  to StandardInclude=pathname  on the LINT
     command line.

_I_n_s_t_a_l_l_a_t_i_o_n_ _F_i_l_e_s_:
    An  installation   file  specifies   the  pathnames  for
software and  data files  used by  LINT.  Installation files
are text files made up of comment lines and option lines.

Comment lines:
     Any line  whose first  non-blank character is # will be
     taken as  a comment.   Blank  lines are also considered
     comments.

Option lines:
     Option lines have the format

          Keyword=pathname

     In this  documentation, keywords  are written with some
     letters in  upper case and some in lower case.  You may
     abbreviate keywords  by omitting  any  or  all  of  the
     letters shown in lower case.  The remaining letters may
     be  entered   in  either   upper  or  lower  case;  the
     documentation simply  uses upper  case  to  show  which
     characters may not be omitted.

    In this version of LINT, possible option lines are:

Include=pathname
     gives the directory containing the LINT include files.

Library=pathname
     gives the directory containing the LINT libraries.

Program=pathname
     gives the  directory  containing  the  LINT  executable
     files (CPP, and so on).
















Page 34                                       November, 1995
