Read each statement in a procedure and summarize the logical purpose of the statement, ignoring any comments.
Determine what the program is actually doing, as opposed to what it was intended to do.
What are the values computed by a procedure?
What are the side effects caused by invoking a procedure?
We tend to believe comments, even when they contradict our interpretation of the source code. It may be necessary to strip the comments before reading.
We tend to believe the names given to procedures and variables. It may be necessary to rename them to arbitrary strings before reading.
Read the text, while marking it to identify problems.
Mark (highlight or underline) definitions of variables with one color and mark uses of the same variables with another color.
Read with a specific input data set in mind, and mark statements the first time you determine they will be executed.
Read looking for unknown patterns. Underline or highlight common elements of repeated patterns that you identify. Go back over your listing and find candidate patterns that have some missing elements. Decide whether you have two different patterns, one pattern with elements missing from some instances, or one pattern with extraneous elements in some instances.
Read looking for an exception to a known pattern. Underline or highlight just the elements of the pattern in question. Review all the instances of the pattern, looking for omitted or extraneous elements.
Use a syntax-directed editor or browser to do one of the following:
Read the control flow of a procedure or calling tree of the program in a breadth-first manner. Open all the control-flow constructs at the same nesting level, read them top to bottom, and proceed to the next level until done.
Read the control flow of a procedure or calling tree of the program in a depth-first manner. Open a control-flow construct until it’s completely unfolded, and read the entire nested construct. Repeat for each top-level nested construct, top to bottom, until done.
Use a class-hierarchy browser to do one of the following:
Review the inheritance hierarchy of the program in a breadth-first manner. Open all the derived classes at the same nesting level, review them top to bottom, and proceed to the next level until done.
Read the inheritance hierarchy of the program in a depth-first manner. Open a base class until it’s completely unfolded, and review the hierarchy. Repeat for each base class, top to bottom, until done.
Use a word processor that supports underlining and multiple text colors to read the text and apply one of the refined tactics to the program text.