Debugging

``C Code. C code run. Run, code, run... PLEASE!!!'' - Barbara Tongue

If you use enums, the first enum constant should have a non-zero value, or the first constant should indicate an error.

      File.Delete(TheFile => TheFile,
                  Success => OK);
      AuditSystemFault := AuditSystemFault and not OK;
Uninitialized values will then often ``catch themselves''.

Check for error return values, even from functions that ``can't'' fail. Consider that close() and fclose() can and do fail, even when all prior file operations have succeeded. Write your own functions so that they test for errors and return error values or abort the program in a well-defined way. Include a lot of debugging and error-checking code and leave most of it in the finished product. Check even for ``impossible'' errors. [8]

Use the assert facility to insist that each function is being passed well-defined values, and that intermediate results are well-formed.

Build in the debug code using as few #ifdefs as possible. For instance, if ``mm_malloc'' is a debugging memory allocator, then MALLOC will select the appropriate allocator, avoids littering the code with #ifdefs, and makes clear the difference between allocation calls being debugged and extra memory that is allocated only during debugging.

      File.Delete(TheFile => TheFile,
                  Success => OK);
      AuditSystemFault := AuditSystemFault and not OK;

Check bounds even on things that ``can't'' overflow. A function that writes on to variable-sized storage should take an argument maxsize that is the size of the destination. If there are times when the size of the destination is unknown, some `magic' value of maxsize should mean ``no bounds checks''. When bound checks fail, make sure that the function does something useful such as abort or return an error status.

      File.Delete(TheFile => TheFile,
                  Success => OK);
      AuditSystemFault := AuditSystemFault and not OK;

In all, remember that a program that produces wrong answers twice as fast is infinitely slower. The same is true of programs that crash occasionally or clobber valid data.