| Run-time Debugging using Scaffolding |
An indispensable debugging technique is the use of temporary output statements ("scaffolding") in a program to trace its behavior at run-time. The effective use of output permits you to methodically track down and eliminate bugs in a program. Once the program is correct, the scaffolding is removed (or switched off by using a flag).
Frederick Brooks, in his software engineering classic Mythical Man Month, points out that scaffolding is a term is taken from the construction trade.
By inserting scaffolding into a program you can inspect the value of key variables as your program runs. This information allows you to confirm your assumptions about what your program is doing and how it works.
Using temporary couts to display relevant values is key: displaying every value in the program can make it harder to find an error. Determining which values are relevant takes time and experience.
The three most important aspects of debugging and real estate
are the same: Location, Location, and Location. - R. Pattis
In programs with multiple functions, scaffolding can be placed at the top and bottom of a function to display passed values, and to help determine whether control made it to that point in the program or not:
/* isAbundant() --------------------------------------------------
* returns true if k is abundant (sum of proper divisors > k)
*
int isAbundant(int k){
//scaffolding line
cout << endl << "Start of isAbundant(). k = " << k << endl;
//code for isAbundant
. . .
//scaffolding line
cout << endl << "End of isAbundant(). sumOfDivisors = " << sumOfDiv << endl;
}