Ten Rules for Developing Safety-Critical Code

Bookmark and Share

June 20th, 2006

Of the professional journals that I force myself to read each month, IEEE Software and IEEE Computer are usually the most relevant and interesting. In the June 2006 issue of IEEE Computer, I found a short, but very practical article by Gerard Holzmann entitled “The Power of 10: Rules for Developing Safety-Critical Code.” The entire human race can see an abstract of the article here; but you have to be an IEEE member to get the full-text PDF.

The article contains a discussion and “rationale” for each of the rules; but here’s a quick summary:

  1. Restrict all code to very simple control flow constructs — do not use goto statements, setjmp or longjmp constructs, or direct or indirect recursion.
  2. Give all loops a fixed upper bound. It must be trivially possible for a checking tool to prove statically that a loop cannot exceed a preset upper bound on the number of iterations.
  3. Do not use dynamic memory allocation after initialization.
  4. No functoin should be longer than what can be printed on a single sheet of paper in a standard format with one line per statement and one line per declaration. Typically this means no more than about 60 lines of code per function.
  5. The code’s assertion density should average to minimally two assertions per function.
  6. Declare all data objects at the smallest possible level of scope.
  7. Each calling function must check the return value of nonvoid functions, and each called function must check the validity of all parameters provided by the caller.
  8. The use of the preprocessor must be limited to the inclusion of header files and simple macro definitions. Token pasting, variable argument lists (ellipses), and recursive macro calls are not allowed.
  9. The use of pointers must be restricted. Specifically, no more than one level of dereferencing should be used.
  10. All code must be compiled, from the first day of development, with all compiler warnings enabled at the most pedantic setting available. All code must compile without warnings. All code must also be checked daily with t least one, but preferable more than one, strong static source code analyzer and should pass all analyses with zero warnings.

What intrigues me is that most, if not all, of these guidelines, could have been organized and published thirty years ago, if not earlier. That’s not a criticism of the current publication, but merely an observation that (a) some of the fundamentals of good programming haven’t changed, which is refreshing; and (b) the guidelines need to be published, for the benefit of a younger generation of programmers who are developing ever more complex safety-critical systems.

Mr. Holzmann writes “developers are currently using this rule set experimentally at Jet Propulsion Laboratory (JPL) to write mission-critical software, with encouraging results.” That’s terrific, and it might help avoid some future embarrassments, such as the $125 million software error in the 1999 Mars Climate Orbiter rocket, in which one article (see “Poor testing doomed Mars missions, officials say,” Government Computing News, Apr 17, 2000) reported that

“The reports cite a number of problems in the planning, design and execution of the Mars Climate Orbiter but blamed its failure on a single line of trajectory code. [emphasis added]

“NASA officials have said that Lockheed Martin supplied code programmed in English units of measure rather than metric units. The errant data likely caused computational errors that either sent the $125 million craft spinning off into space or caused it to disintegrate in Mars’ atmosphere.”

Leave a Reply