CLINT V1.41 ÄÄÄÄÄÄÄÄÄÄÄ The Ultimate C Source Checking Tool (c) 1992 R&D Associates - All Rights Reserved ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ ³ R&D Associates, 16 High Street, Rainham, ³ ³ Kent ENGLAND, ME8 7JE ³ ³ ³ ³ Tel: (0634) 361668 ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ** NEW ** R&D Associates can be contacted on ³ ³ COMPUSERVE by mailing user ID: ³ ³ ³ ³ 100013,1042 ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ **** NEW **** ÄÄÄÄÄÄÄÄÄÄÄÄÄ In V1.41 added -x switch which releases 50K more memory to CLint, but makes checking fractionally slower. Great for BorlandC++ with Windows! WHAT IS CLINT? ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLint is a tool which reads the source files of your C programs, and generates reports about possible problems. As it can look at ALL the files in a program, it is able to report far more than any C compiler can. Use CLint while developing your programs, and you'll be assured of type safe linkage, efficient code, and excellent portability. This version of CLint is released as SHAREWARE. This means that you use it on a try-before-you-buy basis. If you find CLint useful, you must register. We'll then send you the latest version, with more documentation, and you'll receive news of updates and technical support. R&D Associates regrets that it is unable to provide any support for it's shareware products without registration. Please read the file LICENSE.DOC for more details. INSTALLATION ÄÄÄÄÄÄÄÄÄÄÄÄ PLEASE NOTE: If you already have a CLINT.CFG file you should rename it to CLINT.OLD before installing this upgrade and then, after installation, type: COPY CLINT.OLD CLINT.CFG Otherwise your current configuration settings will be lost. To install this version of CLint insert the supplied CLint disk in the drive (we assume drive A: here), then type: A: SETUP C:\CLINT assuming C:\CLINT is the directory you want the program to be installed in. Select the compiler you're using, and specify where you're compiler lives. SETUP writes the CLINT.CFG file accordingly. You can use SETUP again at any time to change these choices. Alternatively, if you downloaded CLint from a bulletin board, expand it into the directory of your choice, then type SETUP to select your compiler. Having installed CLint the first thing you may need to do is modify your AUTOEXEC.BAT file to include the line: SET CLINT=C:\CLINT or similar if you installed to a different directory. If you use a ram disk, CLint will run faster if you tell it to place it's temporary files on ram disk. Assuming you have a ram disk called D: then also add to the following line to your AUTOEXEC.BAT file: SET TMP=D: (or E: etc.) or SET TEMP=D: WARNING: Don't specify a nonexistent name here, or CLint won't work! Then you should modify your path to include CLint's directory, or (if your path is already long) you can place the following batch file CLINT.BAT in a directory already in your path: @ECHO OFF C:\CLINT\CLINT %1 %2 %3 %4 %5 %6 %7 %8 %9 Finally, you must execute in your CLint directory the batch file most closely matching your compiler. This will construct the CLint library for the compiler. The files are: CTC20.BAT TurboC 2.0 or earlier CTCPP10.BAT TurboC++ 1.0 CBCPP30.BAT Borland C++ 3.0 or earlier CMSC6.BAT Microsoft C 6.0 or earlier CZTC21.BAT Zortech C++ 2.1 or earlier If you are not using one of the above compilers, use CTC20.BAT. Now re-boot your computer to allow the changes to AUTOEXEC.BAT to take effect. PLEASE NOTE: If you change your version of C you will need to run SETUP from the CLint directory when you make the change. CONFIGURING CLINT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can configure CLint to your personal preferences by editing the supplied CLINT.CFG file which looks like this (varies according to what you told SETUP when CLint was installed): # (c) R&D Associates 1992. # CLINT.CFG -IC:\TC\INCLUDE # TurboC++ 1.0 -lC:\CLINTREG\CTCPP10 # Clint Library for TurboC++ 1.0 # # Add additional include directories with -I # Add your Clint library directory with -l # Add your common Clint warning switches: # -wxxx to enable warning xxx, # -w-xxx to diable warning xxx. # As you will see later, you can add any of CLint's options to this file as you see fit. The '-I' line specifies the name of the directory where your compilers's header files are - change this as required. The '-l' line specifies where you keep the library definitions, and the name of the definition file. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE: You MUST specify complete pathnames with -I and -l! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLint searches for CLINT.CFG in the current directory, then in the directory specified in the CLint environment (SET) variable. You should setup the standard CLINT.CFG file to reflect your general needs. If a special case arises in one of your programs, simply copy CLINT.CFG to that directory: CD MYDIR COPY \CLINT\CLINT.CFG and edit it as required. No other use of CLint will be affected. CLint expects that each line in CLINT.CFG is a CLint option which starts with '-' and is followed by an option letter, and any required text. Any number of other lines may be present in the file and will be ignored. You can also comment any line by using '#' like this: -l\clint\cbcpp30 # BorlandC++ 3.0 Such comments are ignored. CLint is insensitive to case in the command line or in CLINT.CFG except as detailed later. USING CLINT ÄÄÄÄÄÄÄÄÄÄÄ In the simplest case, you will use CLint like this: CLINT *.C CLint will read all of the source files, analyse them carefully, and report on any possibly problems, ANSI violations, portability problems and so forth. It assumes that all the files specified are part of one program, and will be linked together, and linked with the run-time library routines specified in CLINT.CFG or with '-l' options on the command line. It checks carefully that symbols declared in one file and used in another have the same declaration in both files; that all functions defined are actually called; that all variables defined are used. If CLint produces no warnings or errors about such things, you can be assured that the program when linked is type-safe. There may be cases where you have run-time libraries supplied by other vendors, or written by yourself. You will need to tell CLint about them to obtain full checking. If you don't, CLint will complain about symbols which are never defined. Let's assume that you have a library called MYLIB in \MYLIB, which has a header MYLIB.H. The first thing to do is verify that there are no errors in MYLIB: CD \MYLIB CLINT *.C Fix any errors reported before proceeding! Then you do: CLINT MYLIB.H -L MYLIBDEF And finally you add the line: -l\MYLIB\MYLIBDEF to CLINT.CFG. (If you don't want to add this line, simply type the '-l' option when you run CLint.) The really important options you may need to use are: -Dname=value define a preprocessor macro -Uname undefine a preprocessor macro -lfile specify a CLint library file to check against When reading header files, CLint distinguishes between header directories specified in CLINT.CFG, and those specified in the command line. The former are assumed to be your compiler or library header files, the latter header files which are part of the program. This is only important when '-w-shd' is used (don't warn about compiler headers - the default), as CLint will only be silent on minor problems in compiler headers - not program ones. The search order for headers which use "file.h" is: 1) Current directory, 2) Directories given in -I in the command, 3) Directories given in -I in CLINT.CFG. For headers which use only (2) and (3) are searched. The built-in preprocessor is a full ANSI implementation. It defines the required preprocessor macros: __LINE__, __FILE_, __DATE__, __TIME__ and also the macros __DOS__ and __CLINT__ with the value '1'. If you require __STDC__ place '-D__STDC__' on the command line or in CLINT.CFG. Some users have encountered problems with compilers which claim to be ANSI, but don't have fully ANSI preprocessors. Lines like: #ifdef (sizeof(int) == sizeof(short)) often in LIMITS.H are a dead giveaway. The ANSI standard specifically prohibits expressions like this: you can't have casts, sizeof, or enumeration constants in a #if expression. It is usually done by compilers that are trying to deduce the model you are using. Compliant compilers define preprocessor symbols instead. THE COMMAND LINE OPTIONS. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLint takes a number of source file names, possibly with wildcards, and analyses these sources. To control the analysis and reporting, a number of options may occur on the command line, or in the configuration file CLINT.CFG. The filenames may be specified in full or in part. Filenames with no extension are assumed to have the extension '.C'. The files are inspected in order of their occurance on the command line. When wild card expansion occurs, the expanded names are ordered alphabetically. All clint options begin with a leading '-' character. Except as described below, options are case insensetive unless the C standard or operating system requires otherwise. Options may occur in any order on the command line, intermixed with file names. The options are read in the order: CLINT.CFG and command line left-to-right which can be important. Options in the command line may override options in CLINT.CFG or earlier options in the command line. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE: CLint searches for CLINT.CFG first in the current directory, and then in the directory specified in your CLINT environment variable. CLint issues no warnings if CLINT.CFG can't be found. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Typing: clint produces a usage screen summarising the options. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -Ipath -ipath 'path' is a directory name. Case may be important in directory names depending on the operating system you use. It specifies a directory to search for header files. There may be as many of these options as required. The order of search for: #include "file" is current directory, -I directories given on the command line, -I directories given in CLINT.CFG. and for: #include is -I directories given on the command line, -I directories given in CLINT.CFG. You can force CLint to forget all the -I options in CLINT.CFG by giving '-I-' or '-i-' on the command line prior to any other include paths. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -Dname -dname -Dname=value -dname=value This option defines a preprocessor macro. Although the option letter is case insensetive, the macro names and values are NOT. The first form defines a macro with default replacement text '1'. The second form gives the replacement text explicitly. For your convenience, you may append several definitions to an option with ';' like this: -Dname1;name2=4;name3=5;name4 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -Uname This option deletes a preprocessor macro. It is not an error to specify a macro which was not defined. It is an error to attempt to undefine: '__TIME__', '__DATE__', '__FILE__', or '__LINE__'. It can be used to undefine '__CLINT__' or '__DOS__' or any symbols defined in CLINT.CFG. As with '-D' you can append several names with ';' like this: -Uname1;name2 The order of '-D' and '-U' is important - you may only undefine macros whose definition precedes the '-U' option. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -o file -O file -ofile -Ofile This option specifies a file to receive CLint's output. By default the output is written to 'stderr'. If you use this option, CLint still writes the source file name it is working on to 'stderr' to show you how it is proceeding. If more than one of these options occur, the rightmost one is used. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -e0 By default CLint stops reading a file if 15 errors are produced, and proceeds to the next file with the message 'Too many errors'. If you use this option the limit is removed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -eNNN Use this option to specify the error limit you need. The default is 15. If this option and '-e0' occur together, the rightmost one is obeyed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -w0 -W0 By default, CLint stops reading a file if 60 warnings are produced, and proceeds to the next file with the message 'Too many warnings'. If you use this option the limit is removed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wNNN Use this option to specify the warning limit you need. The default is 60. If this option and '-w0' occur together, the rightmost one is obeyed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wall A number of CLint's warnings are optional, and OFF by default. This turns all warnings on. See the section on warnings for more details. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -w-all This turns all warnings off. It may usefully occur in CLINT.CFG when followed by '-wxxx' options to turn on only those warnings you need. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wxxx Turn the specified warning on. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -w-xxx Turn the specified warning off. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This is the complete list of warning switches. Any of them may be used in CLINT.CFG or on the command line. Unless changed by CLINT.CFG, those switches marked with '*' are enabled by default. wcom warn of nested comments webr else needs '{' wfbr for needs '{' wibr if needs '{' wwbr while needs '{' wspc advise on spacing wlfb warn of functions longer than 120 lines wlfbNNN warn of functions greater than NNN lines long wtyb typedefing primitive types *wtye warn of typedefing enums *wtyg warn of general (complex) typedefs *wtyp warn of typedefing pointer types *wtys warn of typedefed structs with lower case names wtysU typedefed structs with names not fully in upper case *wstv warn of passed/returned structs (by value) *wcon warn of constant conditions *whdr show warnings in user header files wshd show warnings in system header files *wprn warn of misuse of printf (sprintf, fprintf, etc) *wenu warn of enum misuse *wtri warn about trigraphs *winc warn of multiply included header files *wiag warn of auto aggregate initialisation *wunr warn of unreachable code *welb warn of empty loop bodies *wcil long constant needs 'L' *wsig warn of loss of significance with longs wsig+ warn of loss of significance with any type *wmxp warn of mixed pointers to signed/unsigned char *wenu warn of enum missuse *wnus warn of variables defined but not used *wpro warn of function use without a prototype *wret warn of return missuse SPECIAL OPTIONS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -L file This important option instructs CLint to change it's behaviour, in that it knows that the source files will be headers not program text. Each prototype or external declaration in the source files is written to the 'file' in a form to be later read into CLint using the '-l' option. Note that many errors will be reported if this option is applied to program source, and that the '-L' MUST be upper case. The file name case is only important if your operating system requires. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -lfile This option instructs CLint to read a definition file previously prepared with the '-L' option above. Declarations and usage in your program files will be compared to those recorded in the definition file, and may result in the warning: Warning: 'name' in file(NNN) hides a library symbol in 'file' If this happens, you have defined a function or variable which is also defined in a library. C allows this, but in some cases it may be a bug in your code. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The '-l' option may be used differently in CLINT.CFG: you can use a directory name. For example, suppose that you place all the definition files you created with the '-L' option above in \CLINT\MYLIBS If you want CLint to check usage in ALIB in this directory, you place: -l\clint\mylibs in CLINT.CFG, and on the command line use: -lalib CONTROL OF TYPEDEFS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 'typedef' is often misused. You can control the way CLint reports these misuses in a number of ways: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wtye enables reports of typedefing enums, for example: typedef enum { A, B} THING; provokes the report: "typedefed enum as 'THING'". We consider typedefing enums to be poor practise as discussed elswhere, except for the example given below. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wtys enables reports about typedefing structs or unions without an initial capital letter in the name, -wtysU enables reports about this without the name being all upper case. We consider that at least the name should start with a capital letter, preferably all upper case. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wtyp enables reports about typedefing pointer types. We consider this to be one of the major abuses of typedef. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wtyg enables reports about strange typdefs - for example typedefing an array. We produce this message for any typedef which is complex (not a primitive type, struct, union, enum, or pointer). Complex typedefs are in our opinion dangerous as they hide too much information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -wtyb enables reports about typedefing primitive types such as 'int' with names that are not all lower case. There are occasions where this is useful, but we believe that for clarity the typedef name should always be lower case.