|
Guide Contents 1. Overview 2. Operation 3. Abstract Types |
4. Function Interfaces 5. Memory Management 6. Sharing 7. Value Constraints |
8. Macros 9. Naming Conventions 10. Other Checks Contact: lclint@cs.virginia.edu |
This guide is preserved to maintain old links, but has been replaced by the Splint Manual. |
LCLint is a tool for statically checking C programs. With minimal effort, LCLint can be used as a better lint.[1] If additional effort is invested adding annotations to programs, LCLint can perform stronger checks than can be done by any standard lint.
LCLint User's Guide
Some problems detected by LCLint include:
- Violations of information hiding. A user-defined type can be declared as abstract, and a message is reported where code inappropriately depends on the representation of the type. (Section 3)
- Inconsistent modification of caller-visible state. Functions can be annotated with information on what caller-visible state may be modified by the function, and an error is reported if the modifications produced by the function contradict its declaration. (Section 4.1)
- Inconsistent use of global variables. Information on what global and file scope variables a function may use can be added to function declarations, and a message is reported if the implementation of the function uses other global variables or does not uses every global variable listed in its declaration. (Section 4.2)
- Memory management errors. Instances where storage that has been deallocated is used, or where storage is not deallocated (memory leaks). (Section 5)
- Dangerous data sharing or unexpected aliasing. Parameters to a function share storage in a way that may lead to undefined or undesired behavior, or a reference to storage within the representation of an abstract type is created. (Section 6)
- Using possibly undefined storage or returning storage that is not completely defined (except as documented). (Section 7.1)
- Dereferencing a possibly null pointer. (Section 7.2)
- Dangerous macro implementations or invocations. (Section 8)
- Violations of customizable naming conventions. (Section 9)
- Program behavior that is undefined because it depends on order of evaluation, likely infinite loops, fall-through cases, incomplete logic, statements with no effect, ignored return values, unused declarations, and exceeding certain standard limits. (Section 10)
LCLint checking can be customized to select what classes of errors are reported using command line flags and stylized comments in the code.
This document is a guide to using LCLint. Section 1 is a brief overview of the design goals of LCLint. Section 2 explains how to run LCLint, interpret messages produce, and control checking. Sections 3-10 describe particular checks done by LCLint.
1. Overview
The main goals for LCLint are to:
- Detect a large number of bugs in typical C programs, without producing an unacceptable number of spurious messages. We are willing to accept the possibility that a few spurious messages are produced as long as it enables significantly more powerful checking and the spurious messages can be suppressed easily.
- Support a programming methodology involving abstract types and clean, documented interfaces in standard C programs.
- Provide a gradual transition for programmers. LCLint can be used like a better standard lint with minimal effort. Adding a few annotations to programs enables significantly better checking. As more effort is put into annotating programs, better checking results. A representational effort/benefit curve for using LCLint is shown in Figure 1 (not available in HTML format). As different checks are turned on and more information is given in code annotations the number of bugs that can be detected increases dramatically.
- Provide enough flexibility so that LCLint can be used effectively with a wide range of coding styles. Especially important is making it easy to use LCLint effectively to maintain and modify legacy code.
- Check programs quickly and with no user interaction. LCLint runs faster than most compilers. Libraries can be used to enable fast checking of a few modules in a large program.
LCLint does many of the traditional lint checks including unused declarations, type inconsistencies, use-before-definition, unreachable code, ignored return values, execution paths with no return, likely infinite loops, and fall-through cases. This document focuses on more powerful checks that are made possible by additional information given in source code annotations. [2] Annotations are stylized comments that document certain assumptions about functions, variables, parameters, and types. They may be used to indicate where the representation of a user-defined type is hidden, to limit where a global variable may be used or modified, to constrain what a function implementation may do to its parameters, and to express checked assumptions about variables, types, structure fields, function parameters, and function results. In addition to the checks specifically enabled by annotations, many of the traditional lint checks are improved by exploiting this additional information.
This guide is preserved to maintain old links, but has been replaced by the Splint Manual. | |||
|
Guide Contents 1. Overview 2. Operation 3. Abstract Types |
4. Function Interfaces 5. Memory Management 6. Sharing 7. Value Constraints |
8. Macros 9. Naming Conventions 10. Other Checks Contact: lclint@cs.virginia.edu |