             --------------------------------------------------
                   --- Manual Additions/Modifications ---
             --------------------------------------------------
                       PC-lint for C/C++ Version 8.00o

    This readme.txt supplements the on-line PC-lint manual entitled
    "Reference Manual for PC-lint/Flexelint" found in the installation
    directory under the name "pc-lint.pdf"

    You have permission to print out the reference manual in whole or in
    part only in support of the authorized use of this software and not
    for general distribution or resale.



                  ------ Support for Microsoft .NET ------

    As of patch level 8.00f we support Microsoft .NET.  There is a new
    compiler options file (co-msc70.lnt) for Visual C 7.0 and a new
    environment file (env-vc7.lnt) for Visual Studio 7.0.  A few new
    keywords have been added (__if_exists and __if_not_exists) and we
    can translate Visual C++ project files (with a .vcproj extension) to
    .lnt project files.  That is, when a file with a .vcproj extension
    is given to PC-lint, the .lnt project file will appear on standard
    out.  This is done in a manner similar to .dsp files (see section
    3.6 of the manual).  See also env-vc7.lnt to see how a tool can be
    created to automate the process.

    If a .vcproj file contains multiple configurations then PC-lint will
    accept the first configuration found unless the -dConfiguration=...
    option specifies a configuration other than the first.

    Patch level 8.00g fixed a few glitches.  The __if_exists 'statement'
    is not really a statement since it appears in a number of different
    contexts and so that had to be rewritten at the token level.  The
    .vcproj files had a little wrinkle.  We previously looked for
    "Source Files" but this categorization could not be relied on so now
    we just look for files with any of our C++ extents (extents can be
    added by the user via the +cpp option) or a .c extent.


               ------ Support for Borland Project Files ------

    As of patch level 8.00j we support the Borland 6.0 Project Files
    (.bpr) in a manner similar to the support for Microsoft .dsp and
    .vcproj files.  That is the command:
    
          lint-nt  a.bpr
    
    will generate to standard out options and names of modules that it
    finds within the project file.  The default location of the Borland
    system is:

    
          c:\program files\borland\cbuilder6
    
    This can be modified by presetting macro BCB.  Thus
    
      lint-nt -d"BCB=c:\\my program files\\borland\\cbuilder6" a.bpr
    
    is the appropriate command if the location of CBuilder6 is in the
    directory specified.


                 ------ Printing the Reference Manual ------

    You have permission to print out the Reference Manual (or other
    related documentation) in whole or in part in support of the use of
    this software.


                          ------ What's New ------

    To find out what we've added to the product since Version 7.50,
    check out Chapter 18 "What's New" in the Reference Manual.


                           ------ Front End ------

    Your linting experience will be considerably enhanced by adapting
    your favorite editor or compiler environment to the task of
    sequencing from error to error.  See Section 3.5 of the Reference
    Manual.


                        ------ Multiple Passes ------

    By default, PC-lint/FlexeLint will go through all your modules in
    one pass.  For projects not previously linted there will be enough
    messages to look at.  However, with just one pass, you will not be
    taking full advantage of our new interfunction value tracking.  With
    just one pass, we will not know about dangerous return values for
    functions that are defined later than they are called, and we will
    not know about dangerous arguments for functions that are defined
    early.  To introduce a second pass you need only to add the command
    line option:

        -passes(2)

    or, if this syntax presents a problem with your Shell, you may use:

        -passes[2]

    or, in some cases,

        -passes=2
    is needed.

    See Section 9.2.2, "Interfunction Value Tracking".



                      ------ Additional Options ------

    The following options have been added.

    o  Commercial @ is a modifier (+f@m)
       This is a feature required by some embedded compilers that employ
       a syntax such as:
       
             int @interrupt f() { ... }
       
       The @interrupt serves as a modifier for the function f (to
       indicate that f is an interrupt handler).

       Normally '@' would not be allowed as a modifier.  If the option
       +f@m is given then '@' can be used in the same contexts as other
       modifiers.  There will be a warning message (430) but this can be
       suppressed with a -e430.  The '@' will otherwise be ignored.  The
       keyword that follows should be identified either as a macro with
       null value as in -dinterrupt= or as a reserved word using
       +rw(interrupt).

    o  Explicit Throw flag (+fet)
       In early releases of 8.0 (8.0d and earlier) we provided a method
       of checking exception specifications to prevent exception leaks,
       etc.  Unfortunately we were too aggressive and a number of
       programmers pointed out that since a function that doesn't
       declare to throw can throw any exception, then it is at least
       theoretically possible that by adding an exception specification
       to a function that doesn't have one, you will induce the dreaded
       unexpected() call.

       So we made the appropriate modifications and we began getting the
       opposite complaint.  Some programmers were quite happy with the
       old system since it allowed them to track and control their own
       exceptions especially in situations where library functions with
       undocumented exceptions were non-existent.

       To resolve the problem and make everyone happy, version 8.00g has
       a new flag.  The Explicit Throw flag (+fet) is normally OFF.  If
       the flag is OFF then the absence of an exception specification
       (the throw list for a function) is treated as a declaration that
       the function can throw any exception.  This is standard C++.  If
       the flag is ON, however, the function is assumed to throw no
       exception.  In effect, the flag says that any exception thrown
       must be explicitly declared.  Consider
       
             double sqrt( double x ) throw( overflow );
             double abs( double x );
             double f( double x )
                 {
                 return sqrt( abs(x) );
                 }
       
       In this example, sqrt() has an exception specification that
       indicates that it throws only one exception (overflow) and no
       others.  The functions abs() and f(), on the other hand, have no
       exception specification, and are, therefore, assumed to
       potentially throw all exceptions.  With the Explicit Throw flag
       OFF you will receive no warning.  With the flag ON (with a +fet),
       you will receive Warning 1550 that exception overflow is not on
       the throw list of function f().

       The advantage of turning this flag ON is that the programmer can
       obtain better control of his exception specifications and can
       keep them from propogating too far up the call stack.  This style
       of analysis is very similar to that employed quite successfully
       by Java.

       The disadvantage, however, is that by adding an exception
       specification you are saying that the function throws no
       exception other than those listed.  If a library function throws
       an undeclared exception (such as abs() above) you will get the
       dreaded unexpected() function call.  See Scott Meyers "More
       Effective C++", Item 14.

       Can you have the best of both worlds?  Through the magic of
       macros it would appear that you can.  Define
       
             #define Throws(X) throw X
       
       which then is used as:
       
             float f( float x ) Throws((overflow,underflow))
                 { ...
       
       Notice the required double set of parentheses which are needed to
       get an arbitrary list of exceptions into a single macro.

       When you compile you can define Throws to be null and when you
       lint you can define Throws as above.  This can be done most
       easily by doing a #ifdef on the _lint preprocessor variable
       (defined while running our product).

    o  Function takes Custody flag (ffc)
       This flag is normally ON.  It signifies that a function will
       automatically assume custody of a pointer if the argument is not
       of the form const T * where T is some type and is not library.
       Turning this flag OFF (with a -ffc) will mean that a given
       function will not take custody of a pointer unless explicitly
       directed to do so via a custodial semantic for that function and
       argument.  See option -sem.  See also message 429.

    o  The Inhibit Inference flag (fii)
       This flag is normally OFF.  It had been by default ON in versions
       of PC-lint/FlexeLint prior to versions 8.00m.  The purpose is to
       suppress inference formation during Specific Walks and during the
       evaluation of expressions involving nul-terminated strings.
       These inferences were prone to error and were resulting in
       undeserved messages.

       Owing to steady progress in the accuracy of making such
       inferences the flag has been made default OFF.  To obtain the
       prior behavior (i.e.  as it was in version 8.00L) turn the flag
       on with +fii.

    o  Macro Concatenation Flag (+fmc)
       If the flag is ON, a token immediately following a macro with
       parentheses, will, in effect, be pasted on to the end of the last
       token of the macro replacement.  For example, the code
       
             #define A() a
             int A()x;
       
       will normally be greeted with an error according the ANSI/ISO
       standards because this is equivalent to:
       
             int a x;
       
       However if the Macro Concatenation flag is turned on (using the
       option +fmc) the two names are in effect pasted together to
       produce the equivalent of:
       
             int ax;
       
       Prior to the Ansi standard the only way to perform a
       concatenation of this kind was through the device described
       above.  Now the approved mechanism is through the ## operator.
       The option is a means of supporting older programs that are still
       employing the older technique.

    o  Treat carriage Return as Newline (+frn)
       If this flag is ON, carriage return characters (0x0D) in the
       source input not followed by a Newline (0x0a) are treated as
       Newline characters (i.e., as line breaks).  This is necessary to
       process Macintosh style source code on the PC or Unix or their
       derivatives.  With this flag ON all three conventions (NL alone,
       CR alone, and CR NL in combination) are taken to be a Newline so
       that you may mix header files.

    o  -A(C90)
       The -A option (strict ANSI) has been upgraded to conform to the
       C99 standard.  In particular it no longer complains about //
       comments in C code.  To obtain the older style you can use the
       option -A(C90) which says that if the module is a C module it
       should conform strictly to the version of C identified as C90.

    o  multi-thread support
       A number of customers have asked for some kind of multi-thread
       support.  In particular they have asked us for a way to designate
       some data as 'Shared' so that only functions that are also marked
       'Shared' can access the data; also, Shared functions can only
       access Shared data and none other.  If it were not for the second
       criterion you could use the volatile qualifier.

       It so happens that there are a number of old modifier flags that
       can be used for this purpose.  One such is the keyword 'fortran'.
       This keyword is normally not active.  When it was active
       compilers would use the modifier as a clue to employ a
       fortran-like calling sequence for any function so designated.
       Lint would simply ignore these intended semantics and restrict
       its usage to ensuring that declarations would be consistent with
       respect to this modifier.  For example, you wouldn't want to pass
       a pointer that points to a Fortran function to a pointer that
       points to a non-fortran function.  These simple
       type-qualification semantics can be used as the basis for a new
       keyword, in this case 'Shared'.

       For example:
       
             //lint -rw_asgn(Shared,fortran)
             struct X { void f() Shared; void g(); ... };
             X Shared a;
             X b;
             ...
             a.f();   // OK
             a.g();   // Error
             b.f();   // Error
             b.g();   // OK
       

       Using functions rather than member functions we can obtain the
       same effect.
       
             //lint -rw_asgn(Shared,fortran)
             struct X { ... };
             void f( struct X Shared * );
             void g( struct X * );
             struct X Shared a;
             struct X b;
             ...
             f( &a );   // OK
             g( &a );   // Error
             f( &b );   // Error
             g( &b );   // OK
       

       In addition to 'fortran' there are a number of other old
       modifiers that could be employed including: 'pascal',
       '_fastcall', and '_loadds'.

       Any such modifier that is used in the formation of a type will be
       embedded within that type when the type is displayed for
       diagnostic purposes.  The name that is used by default will be
       the original qualification name.  This name will be overridden
       when the -rw_asgn option assigns a modifier to some new name.



                ------ New or Improved Error Messages ------


    89   Argument or option too long ('String') -- The length of an
         option (shown in String) exceeds an internal limit.  Please try
         to decompose the option into something smaller.  At this
         writing the limit is 610 characters.

    155  Ignoring { }'ed sequence within an expression, 0 assumed --
         Some compilers support what looks like a compound statement as
         a C/C++ expression.  For example to define the absolute value
         of an integer which guarantees that it will be read only once
         you may use:
         
               #define abs(a) { int b = a; b >= 0 ? b : -b; }
         
         The last expression in the list is the result.  To
         syntactically support the construct without running amuck we
         recognize the sequence and issue this message.  If you want to
         use the facility just suppress the message.

    326  String 'String ...' too long, exceeds Integer characters -- A
         string (first 40 characters provided in the message) exceeds
         some internal limit (provided in the message).  There is no
         antidote to this condition in the form of an option.  FlexeLint
         customers may recompile with a redefinition of either M_STRING
         (maximum string) or M_NAME (maximum name).  To override the
         definition in custom.h we suggest recompiling with an
         appropriate -dvar=value option assuming your compiler supports
         the option.

    584  Trigraph sequence (??Character) detected -- This message is
         issued whenever a trigraph sequence is detected and the
         trigraph processing has been turned off (with a -ftg).  If this
         is not within a string (or character) constant then the
         trigraph sequence is ignored.  This is useful if your compiler
         does not process trigraph sequences and you want linting to
         mirror compilation.  Outside of a string we issue the Warning
         but we do translate the sequence since it cannot make syntactic
         sense in its raw state.

    660  Option 'String' requests removing an extent that is not on the
         list -- A number of options use the '-' prefix to remove and
         '+' to add elements to a list.  For example to add (the most
         unusual) extension .C++ to designate C++ processing of files
         bearing that extension, a programmer should employ the option:
         
               +cpp(.C++)
         
         However, if a leading '-' is employed (a natural mistake) this
         warning will be emitted.

    686  Option 'String' is suspicious because of 'Name' -- An option is
         considered suspicious for one of a variety of reasons.  The
         reason is designated by a reason code that is specified by
         Name.  At this writing, the only reason code is 'unbalanced
         quotes'.

    814  useless declaration -- A tagless struct was declared without a
         declarator.  For example:
         
               struct { int n; };
         
         Such a declaration cannot very well be used.

    1076 Anonymous union assumed to be 'static' -- Anonymous unions need
         to be declared static.  This is because the names contained
         within are considered local to the module in which they are
         declared.

    1083 Ambiguous conversion between 2nd and 3rd operands of
         conditional operator -- If the 2nd operand can be converted to
         match the type of the 3rd, and the 3rd operand can be converted
         to match the type of the 2nd, then the conditional expression
         is considered ill-formed.

    1549 Exception thrown for function 'Symbol' not declared to throw --
         An exception was thrown (i.e., a throw was detected) within a
         function and not within a try block;  moreover the function was
         declared to throw but the exception thrown was not on the list.
         If you provide an exception specification, include all the
         exception types you potentially will throw.  [23, Item 14]

    1550 exception 'Name' thrown by function 'Symbol' is not on
         throw-list of function 'Symbol' -- A function was called (first
         Symbol) which was declared as potentially throwing an
         exception.  The call was not made from within a try block and
         the function making the call had an exception specification.
         Either add the exception to the list, or place the call inside
         a try block and catch the throw. [23, Item 14].

    1560 Uncaught exception 'Name' not on throw-list of function
         'Symbol' -- A direct or indirect throw of the named exception
         occurred within a try block and was either not caught by any
         handler or was rethrown by the handler.  Moreover, the function
         has an exception specification and the uncaught exception is
         not on the list.  Note that a function that fails to declare a
         list of thrown exceptions is assumed to potentially throw any
         exception.




                        Gimpel Software
                        January, 2004
