|
|
What is CodeInspect
CodeInspect is a code source inspector or a lint as commonly known. It analyses your C/C++ source code and reports non-portable, suspicious or plain wrong code. CodeInspect can be used to enforce good coding practices or corporate coding rules, to help automate the code review process, to check for code portability and to perform quality assurance testing directly on the source code. CodeInspect can currently enforce 24 rules. Each rule can be enabled or disabled depending on the user's preferences. How to Use CodeInspect There are many different ways to use CodeInspect: 1- Using CodeInspect.exe
2- Directly inside Visual C++. You can use CodeInspect directly from the Visual C++ IDE. To integrate CodeInspect into MSVC do the following: Choose Tools/Customize/Tools and add a new item to the list, then fill the field like this:
CodeInspect can now be used from within MSVC by selecting the CodeInspect menu item from the Tools menu. The whole project will be inspected. The result will be send to the output window. You can double-click on a message and the IDE will jump to the line of code where the message occurred. If you want to inspect your project using a different configuration than the default one, you can enable the option Prompt for arguments and specify the correct configuration on the Tool arguments dialog box. 3- Using your existing makefiles. You can use CodeInspect with your existing makefiles. The only requirement is that inside the makefile the compiler (CL) is never called directly but always via a nmake macro. Like this:
Fortunately, the Visual C++ generated makefiles are doing exactly this. To inspect an entire makefile, you just have to execute it with nmake while redefining the CPP macro on the command line:
4- With the command line utility DspLint. DspLint is a tool that inspect an entire Visual C++ project. To use DspLint you simply have to specify the name of your project on the command line.
This will inspect all sources in project MyProject.dsp using the default configuration. Optionally, you can force DspLint to use a particular configuration by putting the name of the configuration after the name of the project file.
5- With the command line utility Lint. If you don't have a lot of files to inspect, you can execute Lint directly. For example, if you want to inspect a file called test.cpp:
Or if you have two files:
Lint support the same options accepted by Microsoft's CL compiler. You can therefore specify command line options as if Lint was CL.
How to Configure CodeInspect
Here is a description for each option that can be customized. Ignore duplicate messages
Use INCLUDE environment variable
Ignore warnings in system headers
Use Visual C++ directories setting.
System include directories
Ignore directories
Messages list
DspLint command-line syntax DspLint allows you to inspect an entire project created by Visual C++. DspLint works by extracting all the necessary information from the project (.dsp) file and calling Lint for each source file with the appropriate options. DspLint [/c] <myprj.dsp | mywksp.dsw> [<configname>] If you specify a workplace (.dsw) file, DspLint will look for a project (.dsp) file with the same name in the same directory. If the file doesn't exist, an error will occur.
Optionally, you can specify to DspLint what configuation to
use to parse the project's files with configname. For example, Lint
will not parse the code within an /c : This option displays the available configurations for the project without inspecting the source code. Usage example dsplint project.dsp dsplint project.dsw dsplint /c project.dsw dsplint project.dsp "Project - Win32 Debug" dsplint project.dsp "Project - Win32 Release" Lint command-line syntax The Lint command line utility uses the following syntax: Lint [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...] This syntax is exactly the same as the one supported by Microsoft's CL compiler. Lint will ignore the options that are not needed for its execution and take meaningful actions for some options that affect the way Lint parses a file. For example, Lint will recognize the /D (Macro Definition) option and add the macro to your source file. It is important to note that Lint is designed to act as a substitute for CL. You don't have to learn a different set of options for Lint and for CL. This make it possible to just substitute Lint for CL in your makefile and execute it with nmake. Lint will then parse your source code just fine. Fatal Error F1001Unknown messageThe message is unknown to the parser. Fatal Error F1002Out of memory ('file', 'line number')Lint ran out of memory during execution. You may need to quit all others applications before executing lint. If that doesn't work, you may need a computer with more memory in order to parse the file. 'file' and 'line number' represent the location in the lint source code where lint failed to allocate more memory. Fatal Error F1003Process memory is corrupted ('file', 'line number')Lint cannot continue execution due to memory corruption. This is most likely due to a defect in the lint program. Please fill a bug report. 'file' and 'line number' represent the location in the lint source code where lint detected the memory corruption. Fatal Error F1004Internal parser error('file', 'line number')Lint has entered in an invalid state and cannot continue execution. This is most likely due to a defect in the lint program. Please fill a bug report. 'file' and 'line number' represent the location in the lint source code where lint entered in an invalid state. Fatal Error F1005Window SEH errorLint cannot continue execution due to an unexpected Windows Structured Error Exception. This is most likely due to a defect in the lint program. Please fill a bug report. Parser Error P2001Illegal character 'hex-character'An illegal ASCII character appeared in the source code. The parser will ignore it. Parser Error P2002Unexpected end of fileEnd of file was detected in the middle of a C/C++ construct. An example of this error is when you forget to close a C-style comment. Parser Error P2003Unexpected end of lineA new-line character is illegal at this point in the source code. example
Parser Error P2004File 'filename' not found'filename' could not be found while looking in the include directories list. Make sure the system include directories are correctly set by using the program CodeInspect. Parser Error P2005Cannot open file 'filename''filename' was found but could not be opened. Possible causes:
Parser Error P2006Invalid #include directiveThe line does not form a valid #include directive. example
Parser Error P2007Invalid preprocessing expression constantThe expression inside #if is invalid. example
Parser Error P2008Unexpected #elif directiveThe #elif directive did not appear within an #if, #ifdef, or #ifndef construct. Parser Error P2009Unexpected #else directiveThe #else directive did not appear within an #if, #ifdef, or #ifndef construct. Parser Error P2010Unexpected #endif directiveAn #endif directive is not matched by a beginning #if, #ifdef, or #ifndef directive. Parser Error P2011Invalid preprocessor directiveThe line does not form a valid preprocessing directive. example
Parser Error P2012Identifier expectedLint was expecting a valid identifier at this point but found something else. example
Parser Error P2013Macro parameter 'identifier' redeclaredMacro parameter 'identifier' is used more than once in the parameter list of a macro definition. example
Parser Error P2014')' expectedLint was expecting a closing parenthesis at this point but found something else. example
Parser Error P2015#error directive: 'message'An #error directive was detected while preprocessing file. Parser Error P2016#endif expected before end of fileAn #if, #ifdef, or #ifndef construct was not closed by an #endif. Parser Error P2017#import directive is not supportedThis version of CodeInspect doesn't support the #import preprocessing directive. Future version will. Warning W3001C++ style comment in C sourceA C++ style comment was found in a C source file. While a lot of C compilers accept this as an extension, C code source that contain C++ comments are nonstandard and will cause portability problems with some compilers. Warning W3002; W3003Unused macro constantUnused function constantA macro was defined but is never used. Theses two warnings are more meaningful when detected at the end of a project. Then an unused macro may alert the programmer that he forgot to handle a particular situation or else that the macro is no longer needed. If no longer needed, it may be better to delete the unused macro to avoid confusion and to facilitate maintenance. Warning W3004System header should be included using < and > delimiters : <header>It's a good idea to always include system headers using the <> delimiters and project specific headers using the "" delimiters. Doing so helps to distingue between the two kinds of header and make the code more explicit and easier to understand. example
prefer:
Warning W3005Nonstandard charizing operator '#@' usedThe charizing operator is a Microsoft specific compiler extension. Do not use it if you want your source code to be portable. example
Warning W3006Use of old style C++ ANSI/ISO header 'old-header', prefer 'new-header'A C++ standard header was included in the old way with a .h extension. With the adoption of the C++ standard, header names now contain no extension. For backward compatibility, Visual C++ still provides some headers with the old notation that contain old C++ library code. Those headers should be avoided in favor of the template based new headers. List of old header names with their corresponding new header names
Warning W3007Use of old style ANSI C header 'old-header' in C++ source, prefer 'new-header'A C header was included in a C++ file using the form <header.h>. While this practice is allowed by the C++ standard, a better alternative is to use the form <cheader>. This latter form has the advantage of placing all the declarations and definitions within the scope of the namespace std. List of old header names with their corresponding new header names
Warning W3008'header' is not an ANSI C header'header' is not part of the header list that every C implementation must provide. There is no guaranty that 'header' will be available on another implementation or platform. Enable this warning only if you want your source code to depend only on ANSI C header. This warning is reported only for headers found in the system include paths. example
Warning W3009'header' is not an ANSI/ISO C++ header'header' is not part of the header list that every C++ implementation must provide. There is no guaranty that 'header' will be available on another implementation. Enable this warning if you want your source code to depend only on ANSI/ISO C++ header. This warning is reported only for headers found in the system include paths. example
Warning W3010; W3011Macro constant identifier should be all uppercaseMacro function identifier should be all uppercaseIt is common practice to make the name of macro identifiers all uppercase. Macro can have some undesirable behaviors and giving them all uppercase names makes it easier to spot them in the source. The source is then easier to understand and maintain. example
Warning W3012Parentheses are missing around a complex macroA macro that contains complex expression without being parenthesized is prone to error when expanded inside another expression. Because operator precedence rules apply only after all expansions are done, the result may not be what the programmer would expect (see example). It is then better to always surround all expression macro within parentheses. Note that CodeInspect will report this warning only for macro that looks like expression. example
This line will expand to
Which by operator precedence means:
Variable a will be assigned value 7, not 9 as common sense would imagine by reading the initial nonexpanded expression. This is surely not what the programmer was expecting. A better alternative is to replace the macro ADD by an inline function. Warning W3013Parentheses are missing around a macro parameter 'param'Parentheses are missing around a macro parameter. Macro parameters in the replacement text of a macro definition should always be surrounded by parentheses. Otherwise subtle operator precedence errors could occur if the actual macro argument is a complex expression. This kind of error is similar to the one described in Warning W3012. Note that CodeInspect will report this warning only for macro that looks like expression. example
This line will expand to
Which by operator precedence means:
Variable a will be assigned value 12, not 10 as common sense would imagine by reading the initial nonexpanded expression. This is surely not what the programmer was expecting. A better alternative is to replace the macro MUL by an inline function. Warning W3014A macro argument 'name' with side effects is evaluated more than once after macro expansionThe macro argument 'name' contains side effects and will be evaluated many times because of macro expansion. This will cause some variables to be modified several times without being apparent in the source code. This is most probably a programming error. Don't put expressions with side effects as macro argument. example
After macro expansion the last line will become
After execution a will take value 3, b value 5 and max value 5. b++ will be evaluated twice because b is larger and thus only the second expression after the ? will be evaluated. This kind of code is confusing and hard to maintain and should be avoided. To fix the problem, put the increments on separate line:
A better alternative is to replace the macro MAX by an inline function. Warning W3015Identifier 'name' is reserved for the implementation use'name' is reserved by the implementation and should not be used as an identifier in your source code. The C++ standard states that some names are reserved and should never be used. Currently Lint will emit this warning for :
example // Identifier '_ONE' is reserved for the implementation use #define _ONE 1 Warning W3016Assignment '=' inside an ifA common mistake in C/C++ program is to use '=' instead of '==' inside an if assignment expression. This will result in the left variable to be assigned instead of being compared.
The warning will not occur if the assignment (=) is not the controlling expression.
It is possible to imagine cases where it makes sense to use '=' inside an if, for example:
While this code is valid and correct, it would be better to separate the memory allocation and the test for failed allocation. You then avoid having to use '=' inside an if. This makes the code easier to understand and maintain.
or alternately you can embed the assignment inside parentheses and make the comparison to 0 explicit:
Warning W3017Assignment '=' inside a whileAn assignment '=' is the controlling expression inside a while. This is suspicious! Is this the intent ? Maybe you wanted to write the equality operator '=='. This warning is similar is W3016. example
Warning W3018Enum forward declaration is a nonstandardEnum forward declaration is not part of the C++ standard. Do not use this feature if you plan to port your source code on another compiler or platform. example
Warning W3019Macro 'macro-name' could be a const variableIt is usually preferable to use a const variable instead of a macro. A variable has a scope and a type whereas a macro doesn't obey to scope rules and has no type. For example, if your program contains another identifier that has the same name as the macro but inside another scope, your program will not compile or work correctly because the macro will overwrite the identifier. example
Warning W3020Macro 'macro-name' could be an inline functionIt is usually preferable to use an inline function instead of macro function. Using inline functions has many advantages over macros:
Warning W3021'header' has already been includedIndicate that 'header' has already been included in the same file. The include directive is thus unnecessary and should be removed. example
Warning W3022'using namespace std' is not recommendedBy declaring 'using namespace std' in your program, you are effectively defeating the purpose of namespace. 'using namespace std' will makes all the names from the standard library available as if they had been declared outside the std namespace. It is better to use using-declaration (ex: using std::string) or explicitly prefixing std:: in front of standard library names. This way make it clear if a name comes from the standard library or not example
It is better to write the preceding program like this:
or like this
Warning W3023Assignment to selfAn variable that is assigned to itself was detected in the source code. This is most probably due to a typing error. example
Warning W3024Using == or != with floating point values in dangerousBe very cautious when using == or != with floating point values. Because of the way they are designed, floating point values are only approximate. Floating point operations always introduce small round-off errors and there is no perfect representation of fractions. Use == and != with floating values only if you perfectly understand the consequences of doing so. example This code will cause an infinite loop on Visual C++ 6:
Instead use the relational operator: <, <=, >, >=
|
|
|
|
|
| Copyright © 2006 Yokasoft. All rights reserved |