Expert C Programming

(Jeff_L) #1

explicit cast, or lint comment, but there were several real bugs shaken out by the process:



  • Argument types transposed between function and call

  • A function that was passed one argument, but expected three, and took junk off the
    stack. Finding this cured an intermittent data corruption problem in the streams
    subsystem.

  • Variables used before being set.


The value is not just in removing existing bugs, but in preventing new bugs from
contaminating the source base. We now keep the kernel lint-clean by requiring all source
changes or additions to be run through lint and cstyle. In this way we have not only
removed existing bugs, but are reducing the number of future bugs as well.


Some programmers strenuously object to the idea of putting lint back into the compiler on the grounds
that it slows the compiler down and produces too many spurious warnings. Unfortunately, experience
has proven repeatedly that making lint a separate tool mostly results in lint not being used.


The economics of software is such that the earlier in the development cycle a bug is found, the
cheaper it is to fix. So it is a good investment to have lint (or preferably the compiler itself) do the
extra work to find problems rather than the debugger; but better a debugger find the problems than an
internal test group. The worst option of all is to leave the problems to be found by customers.


Some Light Relief—Some Features Really Are Bugs!


This chapter wouldn't be complete without finishing the story of space missions and software. The


Fortran DO loop story (which began this chapter and arose in the context of Mercury suborbital flights)


is frequently, and wrongly, linked with the Mariner 1 mission.


By coincidence, Mariner 1 was involved with a dramatic software failure, but it happened in quite a
different manner, and was entirely unrelated to choice of language. Mariner 1 was launched in July
1962 to carry a probe to Venus, but had to be destroyed a few minutes after launch when its Atlas
rocket started to veer off course.


After weeks of analysis, it was determined that the problem was in the software, but it was a
transcription error in the algorithm rather than a program bug. In other words, the program had done
what the programmer had supposed, but he had been told the wrong thing in the specification! The
tracking algorithm was intended to operate on smoothed (average) velocity. The mathematical symbol
for this is a horizontal bar placed over the quantity to be smoothed. In the handwritten guidance
equations supplied to the programmer, the bar was accidentally omitted.


The programmer followed the algorithm he had been given exactly, and used the raw velocity direct
from radar instead of the smoothed velocity. As a result, the program saw minor fluctuations in rocket
velocity and, in a classic negative feedback loop, caused genuine erratic behavior in its correction
attempts. The faulty program had been present in previous missions, but this was the first time it had
been executed. Previous flights had been controlled from the ground, but on this occasion an antenna
failed, preventing the receipt of radio instructions and thus causing the on-board control software to be
invoked.


Moral: Even if you could make your programming language 100% reliable, you would still be prey to
catastrophic bugs in the algorithm.

Free download pdf