

             --------------------------------------------------
                   --- Manual Additions/Modifications  ---
             --------------------------------------------------
                       PC-lint for C/C++ Version 9.00f

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


                ------ 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.


       ------ Support for Microsoft through Visual Studio 2010  ------

    Patch 9.00e supports Visual Studio 2010 and the Microsoft Visual
    C/C++ 10.0 compiler (as well as all earlier versions of the
    Microsoft compiler series).  Support comes mainly from the compiler
    options files (co-...lnt).  Thus options files co-msc70.lnt,
    co-msc71.lnt, co-msc80.lnt, co-msc90.lnt and co-msc100.lnt support
    versions 7.0, 7.1, 8.0, 9.0 and 10.0 respectively.

    The file co-msc100.lnt is preconfigured to match the default macro
    settings of the compiler.  However, owing to compiler options the
    settings of these macros are subject to change.  We have therefore
    provided a way to automatically generate the macro definitions.  See
    co-msc100.lnt and/or vs2010-m.cpp.

    Also, starting with 9.00e, PC-lint supports .sln and .vcxproj files
    as described below under ".sln Support" and ".vcxproj Support"
    respectively.


                   ------ What's New in Version 9  ------

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

    We traditionally include Version Shock in our "What's New" section.
    This was inadvertently omitted in producing the document.  So here
    it is.


    ------ Version Shock

    wchar_t -- We are treating wchar_t slightly differently in Version
       9.  The difference would not normally be detected.  See flag -fwc
       in Section 5.5 of the manual.

    Strong Type Change -- We now support dimensional analysis using
       strong types.  This resulted in some changes which are not upward
       compatible.  See Section 9.4 "Multiplication and Division of
       Strong Types".

       You can opt out of this change.  See The Dimension by Default
       flag (-fdd) in Section 5.5 and Jm controls the Multiplier group
       flag (-fjm) also in Section 5.5.


                          ------ 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.


                       ------ Getting Started  ------

    In section 3.2 of our Reference Manual we indicate that you need to
    specify where your compiler header files are located as well as the
    location of any third party libraries you might be using.  This is
    done using one or more -i options.  If you are not aware of where
    your libraries are you can compile (using your compiler, not lint)
    the file called:
    
          where_is_stdio_h.c
    
    The purpose and use of the file is documented as commentary within
    the file itself.  It is designed to find the location of your
    compiler's headers and contains instructions on locating other
    library headers as well.


                       ------ 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 static data tracking or the
    interfunction value tracking.  With just one pass, we cannot say
    very much about static variables.  We may see a variable being set
    to a value but we don't know of intervening functions that may be
    modifying the variable.  We will also 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.  Of course, you can replace the 2 with any number you
    wish.  The larger the number, the more bugs that can be found and
    the more processing time that will be required.

    See Section 10.2 "Value Tracking" in the Reference Manual.


                ------ What's New in the 9.00b Patch  ------

    We have been diligent in responding to users that may have
    experienced difficulties in one of the many new options that Version
    9.00 provides.  These features include Pre-compiled Headers (-pch
    option), Bypass Headers (+/-byph(), etc.) and pre-determined
    predicates.


                ------ What's New in the 9.00c Patch  ------

    We have special author files ('au-' prefix) for porting to 64-bit
    programming.  The names of these files are perhaps self-explanatory:

        au-LLP64.lnt        LLP64 model
        au-LP64.lnt         LP64  model
        au-ILP64.lnt        ILP64 model

    Each of these files references the model-independent file au-64.lnt
    that enables Warnings, Informationals and Elective Notes suitable
    when porting from 32 bits to 64 bits.  The file also contains
    directions for employing strong typing to assist in torture testing
    your code.

    In attempting to track the forthcoming C++ standard we have
    implementations of a number of voted on features.  These are
    available using the option: -A(C++2010) and consist of:

        static_assert()
        Extended friend Declarations
        Adding the long long Type to C++
        C99 Preprocessor Synchronization
        Right Angle Brackets
        'extern template'
        Delegating Constructors
        Using 'auto' to deduce types of variables
        Rvalue References
        New Character Types
        sizeof() for non-static members without 'this->'
        decltype
        Strongly Typed Enums
        A name for the null pointer: nullptr


                ------ What's New in the 9.00d Patch  ------

    In addition to the usual set of miscellaneous bug fixes we have made
    a substantial upgrade to our overload resolution algorithms to
    accomodate some subtle language requirements.

    Some additions have been made to our suite of C++ 0x features
    (activated through the use of the option: -A(C++2010)) and consist
    of:

        'explicit' conversion functions
        explicitly defaulted special member functions

    An important bug was found and fixed in connection with pre-compiled
    headers and MSVC 8.0 and 9.0


                ------ What's New in the 9.00e Patch  ------

    Visual Studio 2010 is now supported.

    Our MISRA support (MISRA C 1998, MISRA C 2004 and MISRA C++) has
    been substantially enhanced and our coverage of the various rules is
    now virtually complete.  See Author files au-misra1.lnt,
    au-misra2.lnt and au-misra-cpp.lnt.

    Improved emulation of the Microsoft header search algorithm.  See
    "Microsoft's nested #include search" below.

    Improved support for embedded systems using the @ location
    specifier.  See "Enhanced support for address-specifiers" below.

    Improved Boost.Typeof support for Visual Studio users owing to
    better emulation of Microsoft's __if_exists keyword.


                ------ What's New in the 9.00f Patch  ------

    9.00f removes a troubling undeserved 1013 introduced in 9.00e.

    A number of MISRA issues were addressed.

    A template bug was removed thereby helping us greatly with our Boost
    lambda support.


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

    The following features have been added since our document was
    produced.

    o  Turning off +source
       You may now turn off the +source option using the option
       --source.

    o  Arguments to compiler code options
       Compiler code options (which have the form -ccode) may in some
       cases now take arguments.  The arguments will typically reflect
       compile options passed to a compiler; thus they will tend to be
       vendor-specific.

       The supported option and argument is:
       
             -cmsc( clr )
       
       This not only sets the compiler to the Microsoft compiler but
       also indicates that the project's code is compiled with the /clr
       option, which enables support for certain core-language
       extensions.  When the above Lint option is given, Lint will
       attempt to gracefully ignore such extensions.  (Without
       -cmsc(clr), Lint will generally assume Standard-conforming code
       and issue errors where some CLR extensions are used.)

    o  .vcxproj support
       A .vcxproj file is a recent addition to Microsoft's Visual
       Studio.  Like its cousin the .vcproj file, a .vcxproj file
       describes a single project, possibly consisting of multiple
       modules.  We now process such files in a manner similar to
       .vcproj files (as described in the manual).  Thus, if you have a
       file named x.vcxproj you may process it as follows:
       
             lint-nt x.vcxproj >x.lnt
       
       This will capture in x.lnt, the module names that are embedded in
       x.vcxproj.  Unlike .vcproj files, we do not (yet) attempt to
       deduce either -i options or -d options.

    o  .sln support
       A file whose extension is .sln is treated by the Microsoft Visual
       Studio as a solution file.  It will contain the names of one or
       more project files.  These can now be processed by PC-lint.  For
       example if you have a file named s.sln it can be processed with
       the following command:
       
             lint-nt s.sln >s.bat
       
       The output (s.bat) will contain a sequence of lint commands, one
       command for each .vcproj or .vcxproj name contained within the
       .sln file.  Each command is similar to the one shown above for
       x.vcxproj.

       The curious reader may wonder why we create an intermediate file
       rather than simply process the entire solution file.  The reason
       is that a .sln file contains information about multiple projects
       and a single run of PC-lint is incapable of handling more than
       one project.  We can handle multiple modules of the same project
       but not multiple projects.  The list of commands that emerge from
       the .sln file represents independent runs of PC-lint.

    o  Enhanced support for address-specifiers
       As indicated in Section 5.8.3 Case '@' of the PC-lint/FlexeLint
       manual, some compilers that target embedded systems provide a
       language extension that enables the user to specify, in a
       declaration of a statically-allocated variable or a function, an
       address where the declared entity is to be stored.  Example:
       
                 int a @ 0xFF02; // 'a' is at memory location 0xff02
       
       Since Version 9.00e we are treating the '@' location not as an
       initializer but as a separate address specifier.  This corrected
       two problems; we were not able to use a location specifier in a
       forward declaration and initializers could not accompany location
       specifiers.  Thus we may now write
       
                 int b @ 0xFF00 = 42; // initializes b, at 0xff00, to 42
       
       So the grammar for /init-declarator/ is:
       
             init-declarator:
                 declarator  [address-specifier]   [initializer]

             address-specifier:
                 '@'     constant-expression
       
       This is now reflected in our parser.

    o  Microsoft's nested #include search
       This information may be considered as an addendum to Section 15.2
       Include Processing, Case 1.

       As of Version 9.00e the option
       
             +compiler(search_actively_including_stack)
       
       has been added to the compiler options file for the Microsoft
       compilers co-msc70.lnt through co-msc90.lnt.  This option has the
       effect of emulating Microsoft's "nested #include search" feature,
       in which an include-directive of the form:
       
             #include "a.h"
       
       causes the search for "a.h" to consider first the directory of
       the including file and then the directories of all other
       actively-including files (from most nested all the way through
       the directory containing the primary source file) before
       considering directories specified by '-i' options.

       The option has the side effect of setting +fdi.


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


    510  File extension 'String' reserved for future versions of this
         product -- File name extensions that are not those recognized
         as implying C++ source code or indirect files for lint or
         pre-compiled headers for lint or lint object modules or project
         files are assumed to be C source code.  If we recognize a new
         file extension in some future version of lint it can be
         beneficial to warn about the use of this file extension in any
         earlier version of lint.  One reason for this is to aid in the
         transition between versions of the product.  During this
         transition period a new file extension may be provided
         unintentionally to a former version of the product resulting in
         surprising behavior.

    1084 Ambiguous use of template-id for instantiation of 'Type' --
         When the language calls for a class template to be instantiated
         and the primary template is "overloaded" via one or more
         partial specializations, there is an attempt to see if the
         template arguments match any of those partial specializations.
         (Note, explicit specializations would have been considered
         before determining that the class definition needs to be
         generated by way of instantiation.)  If multiple partial
         specializations match then:

             - If one of the matching partial specializations is more
               specialized than all others then it is used for the
               instantiation.

             - Otherwise, the program is ill-formed, so Lint issues
               message 1084.

         In the message, the matching partial specializations are
         provided as the list of candidates.  Example:
         
               template<class T1, class T2, int I> class A {};             //#1
               template<class T1, class T2, int I> class A<T1*, T2, I> {}; //#2
               template<class T1, class T2, int I> class A<T1, T2*, I> {}; //#3
               A<int*, int*, 2> a; // ambiguous: matches #2 and #3
                   // (and neither template is more specialized than the other)
         

    1096 A target ctor must be the only mem-initializer in the
         mem-initializer-list of a delegating ctor -- C++0x requires
         that if a constructor delegates to another constructor, then
         the mem-initializer (the region between the colon and the
         function body) must contain only one item, and that item must
         be a call to another constructor (which is called the "target
         constructor").  Example:
         
           struct A
               {
               int n;
               A(int);
               A( const A& p) : A(p.n) {} // Ok
               A() :
                   n(42),  A(32)  // Error 1096
                   {}
               };
         

    1097 Delegating ctor delegates directly to itself, causing infinite
         recursion -- Example:
         
           struct A
               {
               int n;
               A(int x) : A(x){} // Error 1097
               };
         

    1098 Function template specialization 'Symbol' does not match any
         function template -- This message is issued for a declaration
         where the user apparently intended to name a specialization of
         a function template (e.g., in an explicit specialization, an
         explicit instantiation or a friend declaration of
         specialization), but no previously-declared function template
         is matched.  Example:
         
               template<class T> void f( const T& ); // #1

               struct A{};
               template<> void f( const A& ); // Ok
               // (A is the deduced argument to T.)

               struct B{};
               template<> void f( const B ); // Error 1097.
               // (A template argument cannot be deduced for T.)
         

    1099 Ambiguous function template specialization 'Symbol' -- This
         message is issued for a declaration where the user apparently
         intended to name a specialization of a function template (e.g.,
         in an explicit specialization, an explicit instantiation or a
         friend declaration of specialization), but the specialization
         matches multiple function templates, and none of the matched
         templates is more specialized than all of the other matching
         templates.  The candidates (i.e., the matching templates) are
         provided in the message.  Example:
         
               template<class T> struct A {};

               template<class T, class U> void f( T*, U    ); // #1
               template<class T, class U> void f( T,  A<U> ); // #2

               struct B{};
               template<> void f( B, A<B> ); // Ok
               // #1 does not match but #2 does.

               template<> void f( char*, A<int> ); // Error 1099
               // Both #1 and #2 match and neither is more specialized than the
               // other.
         
         This situation can be avoided in at least a couple of ways.
         One way is to explicitly specify one or more template
         arguments.  Example:
         
               // continuing from above...
               template<> void f<char*>( char*, A<int> ); // Ok
               // #1 does not match but #2 does.
         
         Another way is to use SFINAE tactics in the declaration of one
         or more function templates, e.g. with boost::enable_if.

    1100 Declaration of 'Symbol' does not declare an explicit
         specialization, explicit instantiation or friend -- In a
         declaration that explicitly specifies template arguments with
         angle brackets immediately after the name of a function
         template, the declaration must declare either an explicit
         specialization, explicit instantiation or friend.  (Note, an
         explicit specialization always begins with 'template<>' and an
         explicit instantiation always begins with 'template'---without
         angle brackets after the keyword 'template'.)
         
               template<class T> struct A {};

               template<class T> inline void f( A<T> ); // #1
               void f( A<int> ); // #2 // Ok, declares an ordinary function

               void f<char>( A<char> ); // Error 1100
         

    1101 Type of variable 'Symbol' cannot be deduced from its
         initializer -- Example:
         
               int f(void);
               int f(char*);
               auto n = f; // Error
         
         In terms of deduction, this is equivalent to:
         
               int f(void);
               int f(char*);
               template<class T> void g( const T& );
               void h( void )
                   {
                   g( f ); // Error
                   }
         
         Here,  'f' refers to multiple overloaded functions, so it is an
         ambiguous reference and T cannot be deduced.  (Code like this
         could still be well-formed however, e.g. if g is overloaded
         with a non-template function whose parameter type is
         'ptr-to-function returning int taking (char*)'.)

    1102 auto type deduced inconsistently: 'Type' for 'Symbol' but
         'Type' for 'Symbol' -- When multiple variables are defined in
         the same declaration, and when that declaration uses the
         keyword auto as the type-specifier (a feature of C++0x), the
         type for which auto is a placeholder must be the same for each
         variable.  Example:
         
               float g(void);
               char* s();
               auto a = 42; // Ok, auto is 'int'
               auto b = g(); // Ok, auto is 'float'
               auto c = 'q',
                    *d = s(); // Ok, auto is 'char' (for both c and d)
               auto x = 42, y = g(); // Error 1102 here
         

    1103 Type 'Type' is not allowed as an enum-base -- When an
         enumeration type is declared with an explicit underlying type,
         that type must be integral.  Example:
         
               enum A : bool; // ok
               enum B : short; // ok
               enum C : unsigned long long; // ok
               enum D : float; // Error 1103
         

    1104 A reference to enumeration 'Symbol' should not use 'String' --
         Although an enumeration may be declared or defined using a
         scope indicator or an underlying type indicator, these should
         not be applied when simply referencing the enumeration.  E.g.
         
               enum class A { red, green };
               enum class A x;         // Error: don't need 'class'
               enum A : unsigned { red, green };
               enum A : unsigned y;    // Error: don't need ': unsigned'
         

    1105 Use of ref qualification of 'Symbol' inconsistent with
         overloaded function 'Symbol' (Location) -- If an explicit ref
         qualifier ('&' or '&&') of a nonstatic member function is
         employed, an explicit ref qualifier needs to be used with every
         member of the overload set.  Thus:
         
               class A
                   {
                   void f(int) &;  // ok (so far)
                   void f(int);    // 1105
                   void f(double); // 1105
                   void g(int);    // ok (fresh function)
                   void g(double); // still ok
                   };
         

    1106 Initializing value 'String' of enumerator 'Name' cannot be
         represented by the enumeration's underlying type 'Type' -- An
         enumerator is being initialized with a value that is
         inappropriate to the declared type of the initializer.
         Example:
         
               enum E : unsigned char { e = 256 };
         
         The value 256 cannot be represented by an unsigned char.

    1107 Mixing two different kinds of string literals -- Two string
         literals are being concatenated which have different types.
         Examples:
         
               char *s = u"abc" U"def";
               char *q = L"ghi" u"jkl";
         
         This message is issued for mixing strings of char16_t,
         char32_t, and/or wchar_t (as shown).  Literal string
         concatenation of any of these with an ordinary character
         literal is permitted and will receive Informational 707.

    1108 Use of deleted function 'Symbol' defined at 'Location' -- This
         message is issued when a deleted function is used.  Example:
         
               void f( int ) = delete;
               void f( double );
               void g( double d, int n ) {
                   f( d ); // Ok
                   f( n ); // Error
               }
         

    1110 Cycle detected: explicit application of 'Name'::operator->
         causes infinite implicit applications of the same operator --
         When an overloaded operator-> is used as in
         
               a->b
         
         it is effectively expanded to:
         
               a.operator->()->b
         
         And this expansion repeats until an operator-> is found that
         does not yield a class type.  But in the process of evaluating
         this expansion, it might be found that one  of the operators
         returns a class type for which an overloaded operator-> was
         already expanded; in that case, Error 1110 is triggered.
         Example:
         
               struct B;
               struct A { struct B& operator->(); };
               struct B { struct A& operator->(); };
               int  f( A & p ) { p->g(); } // Error
         

    1111 ISO C++ requires an explicit specialization/instantiation to
         appear at namespace scope -- This message is issued at the
         beginning of each explicit specialization/instantiation that
         does not appear at namespace scope.  Example:
         
               struct A {
                   template <typename U> struct B {};

                   // template <>  // Would be ill-formed by ISO C++.
                   //     struct B<int> {};
               };
               template<> struct A::B<int> {}; // Ok.
         
         There is an additional limitation with member class templates
         of class templates.  As with members of a non-template class,
         one cannot write a specialization at class scope.   Example:
         
               template<typename T> struct G {
                   template <typename U> struct H {};
                   // template <>  // Would be ill-formed by ISO C++.
                   //     struct H<int> {};
               };
         
         But the language specification does not even allow this to be
         expressed in a namespace-scope definition; there is no way to
         write an explicit specialization that is a member of a class
         template.  Example:
         
               template<typename T> struct J {
                   template <typename U> struct K {};
               };
               // template<typename T>
               //     template <>  // Would be ill-formed by ISO C++;
               //         struct J<T>::K<int> {};
         
         This is because the rules for explicit specializations say that
         'template<>' is not allowed to appear after a non-empty
         template-parameter-list within the same declaration.  However,
         one may write an explicit specialization that is a member of an
         implicitly-instantiated specialization of a class template.
         Example:
         
               template<typename T> struct L {
                   template <typename U> struct M {};
               };
               template <> template <> struct L<char>::M<int> {}; // Ok
         
         Here, the body of the class L<char> is automatically generated
         by implicit instantiation (otherwise the reference to
         'L<char>::M' would be ill-formed), while the body of
         L<char>::M<int> is provided in the explicit specialization.

         In March of 2009, the ISO C++ committee reviewed a report
         submitted against this example:
         
              struct A {
                 template<class T> struct B;
                 template <class T> struct B<T*> { }; // well-formed
                 template <> struct B<int*> { }; // ill-formed
               };
         
         While it might seem odd that one is able to write the partial
         specialization but not the full specialization, the committee
         (which at the time was in a "feature-freeze" mode and trying to
         finalize a draft for the next International Standard) decided
         that this capability would need to be regarded as an
         "extension", meaning that it could be considered as a new
         feature in a future standard but not as a bug-fix for C++0x.

         Note that the Microsoft compiler implements this extension.
         For that reason, the Lint option
         
               -elib(1111)
         
         appears in recent versions of our configuration files for
         Microsoft compilers.

    1574 Returning the address of an auto variable indirectly through
         reference variable 'Symbol' -- Within a function whose return
         type is reference to some type, a return statement is returning
         a reference which has been initialized (possibly indirectly)
         with an auto variable.  For example:
         
               int &f( int k )
                   {
                   int &r = k;
                   return r;
                   }
         


                        Gimpel Software
                        September, 2010
