This is a rather self-satisfied document, written in the mid-1990’s, which may still have some relevance.
Purpose and Scope
While it is hard to make a silk purse out of a sow’s ear (to create good code from a bad design), it is all too easy to do the reverse.
The principle that clear, readable, understandable source text eases program evolution, adaptation, and maintenance is not dependent on the programming language in which the text is written. The purpose of this document is to indicate those language-independent techniques which can help you to produce source text with these qualities.
‘Source text’ is intended to refer to any document that is produced by people and is intended to be read by people as well as by machines. Some of the guidelines may be applicable to people-only documents as well.
[We might at this point refer to the possibility of Annexes for specific languages. However, I feel that there may be a place for project-independent recommendations for specific languages. This document can’t reasonably become the bible for all coding activity. How far should it go?]
The intended audience includes Programmers, programmers’ Managers, and Reviewers.
- The Ada Quality and Style Guide
See also the Ada 83 printed version,
Ada Quality and Style: Guidelines for Professional Programmers
SPC-91061-N Version 02.00.02 1991
- C Style: Standards and Guidelines, by David Straker
Prentice Hall, 1992
- The C Programming Language, Second Edition by Brian W Kernighan and Dennis M Ritchie
Prentice Hall, 1988
- The Elements of Programming Style (Second Edition), by Brian W Kernighan and P J Plauger
We require many different properties in code, beyond correctness. It should be:
None of these can be achieved unless the prime requirement is met; the code must be understandable. What we need to do is to eliminate barriers to understanding and to provide positive assistance to the reader.
Typical barriers to understanding are:
Slovenliness. If code (or any other document) shows a lack of care in its presentation, what reason is there to suppose that any more care has been spent on its content?
Inaccuracy. A comment that is wrong (or has become wrong) is a certain cause of misunderstanding. And, if one comment is wrong, why should one believe the others?
Inconsistency. lf code is not laid out in a consistent way, the reader’s attention is drawn to the differences rather than to the content. If some variables are given long descriptive names and others are named A, B and so on, the reader is likely to be irritated and to waste the entire team’s time waving the source around as an example of how not to do it.
Complexity. Most of the time, the simplest solution is best. To use a rare and unlikely-looking assembler instruction to accomplish what could be done in two simple instructions is only justifiable in desperate circumstances. (Of course, you should only be using assembler in fairly desperate circumstances anyway; and you should certainly have proved by measurement that it is necessary.)
Abbreviation. Only abbreviate where the abbreviation is widely accepted in the problem domain (not just in programming circles). It may take time to think of a descriptive name for a subprogram; if so, this is a reasonably good indication that your readers will need extra assistance at this point.
Typical aids to understanding are:
Header comments. What’s this file for? what design documents does it relate to? what algorithm does it implement? are there any constraints on the implementation? any pitfalls for the unwary user?
History comments. How often has it been changed? who by? why? (Note, it’s not a good idea to refer solely to the supporting change control documents, especially if they’re on paper. In ten years’ time, after three site moves, the relationship can become tenuous.)
The format and content of Header and History comments are often prescribed by Project standards. It can be worth designing the format so as to allow a tool to extract significant information (for example, the Autodoc format used by Commodore-Amiga can be automatically extracted and turned into an AmigaGuide® hypertext document).
Block comments. Describe the purpose of major chunks of the source (typically individual subprograms or large blocks). Sometimes the description needs to be larger than the code, but try to resist demanding this in Project standards.
Assertions. State what you assume to be true at judicious points in the code. This may be at entry to a subprogram, at entry to a block, and especially on exit from a loop or conditional statement. In C you can often use
assert.hto check this during execution (you maybe shouldn’t leave the assertion active in operational code). In Ada, besides the use of
pragma Assert, you can get some of the same effect by careful use of constrained types; however, in most languages, you’re limited to comments.
An example of assertions is comments in an assembler program, at every label (to which you might jump), of what the registers are expected to contain.
Meaningful names. The words making up the names should not be
runtogetherintoalump, and certainly
NOTINUPPERCASE. Sometimes a
CaseConventioncan be useful; sometimes you can
Use_Initial_Capitals, which would be the Ada convention). As noted above, if it causes you pain to think up a good name, just think how your readers will curse you if you don’t bother.
Named values. Sometimes this has to be done using macros, while other languages allow you (ANSI C, C++) or require you (Ada) to declare such objects to be constant. The latter usually has the advantage of allowing type checking.
Layout. This is the subject of more religious debate than almost anything else. Partly, at least, this is because what is a good layout is a matter of aesthetics.
The ideal solution, from a Project point of view, is to have an IDE which formats the code on the fly.
If that’s not possible, there may be a formatting (pretty-printing) tool available. Tools available include: