To comment or not to comment
Abstract:We see so many poorly commented programs. This article may help you understand why and how to write comments. By Pinter Gabor.
Last year, Charles Calvert and Robert Kozak wrote an excellent article about commenting techniques: "I have a comment...". We see so many poorly commented programs that I think this topic is important enough to address again -- slightly differently. Most code in CodeCentral and even the VCL source modules distributed with Delphi are not commented properly in my opinion.
When can we call a program properly commented?
It depends on who reads the code, and what is the intention of the code.
1. No one will read the source
We write these programs for testing a new feature of a programming language tool, or calculating something quickly. These programs are usually deleted after we learn the new feature or get the result of the calculation. But even if we save them it is unlikely that we will use them again. Programs of this kind are not commented. Sometimes they live longer than we expect, and we find them years after they are written and wonder who wrote them so poorly, why they were written, and what on earth they might do.
2. Only the author will read the source
These programs help us learn more complex things like database handling or graphics. Such programs may perform complex operations, even if the user interface is somewhat sketchy. Help files and additional documentation is rarely made, and we must rely entirely on the comments. Programs that we write in our free time for just the pleasure of creating them are another in this group of programs. We often forget to comment these, thinking that no one but us will see or use them. We think why should these programs be commented at all? But, sometimes they have long lives, and writing comments helps us understand the workings of the programming language. When we buy the next version of the programming language tool these commented programs could help us learn the new features.
3. The source will be read by a team and will be maintained for more than a year
These are the typical commercial programs, and are found everywhere. We can rely on the skills of the team to follow common coding techniques, and comment only those things that are uncommon. Additional documentation and help files usually exist, though they may cover mostly the use of the program and not help much in the maintenance. It often pays to keep a private help file, and place most of the explanation there. The code will be more readable despite the reduced amount of comments, and the explanations will be readily available via context-sensitive help. A typical example is the help file for a new component. A reusable component with a context-sensitive help file is a valuable asset that will help when generating a new project quickly, and help in maintaining an existing one.
4. The source is published and can be read by anyone
If we plan to publish the source either as a freeware, shareware, or part of a commercial package, we must think that users of the program will read it and form their own opinion about our programming skills. Every program of this kind is a sort of reference work. We can assume that users who are interested in the code are good programmers and know how to find information in help files and additional documentation, so we do not have to rely entirely on comments. However, we have to make allowances for programmers with different levels of knowledge and backgrounds, and explain everything in detail. Help files are very good at explaining the general structure and the intent of the code, while comments can explain the finer details. There is another advantage of commenting the program well: if users understand the way program works they might be able to help in improving it and finding bugs.
5. Example code for articles or books
These are the most critical programs of all, because they will be read by people who do not understand every aspects of the program, and may not be able to use the information provided separately. Here we have to explain how the program works and why, often repeating with different words what is in the help file. We have to be very careful to balance the information we give in comments, in printed or electronic documentation, and in help files. If we rely too much on information provided elsewhere, the code will be difficult to read. On the other hand, if we write everything in the comments it will bury the code and give the impression that these programs are too complicated.
Categories of comments
Explanation of tricky code
We cannot always avoid using tricky code. In time-critical parts of the program we may have to resort to machine-dependent tricks and even to the use of assembler. The good news is that usually only a tiny portion of the code is time-critical, so commenting every line is not really a burden.
If it is possible to rewrite the code in a less tricky manner, that may be worthwhile. An example is the conversion of a 32 element long Pascal style set to a packed binary C record. Internally both are stored as 32-bit integers, each bit corresponding to one element. The standard conversion uses the "in" operator to test every bit in the Pascal set, and sets or resets the bits in the C record one by one. It is 64 assembly instructions long, it does not make any assumption on the way of storage and easily understandable even without comments. The tricky way is only two assembly instructions long, moving one doubleword to the other.
Markers
Markers are used as temporary notes to yourself or other programmers on your team marking debug lines or unfinished code fragments. When the project is completed these markers, and often the code they refer to, are deleted.
Separators
In the early days of programming files were short, compiled separately and linked. A good rule of a thumb was to keep the file length under 100 lines. Memory was small and editors were cumbersome. With the emergence of object-oriented programming and the growing size of projects, these rules no longer apply. Editors can handle any length file, compiling is done in seconds, but programs are much, much bigger. Ten years ago a million-line program was unthinkable, nowadays-even editors can be that big. Windows.pas is only a header file but 3124 lines long and it is not overloaded with comments. Usually a group of similar components and subroutines are kept in one file. The file length is several thousand lines long. To manage files that big they are separated into sections by separator comment lines. For example the interface is the first section, global object definition is the next, all the subroutines of one object are in the following section, and the initialization/finalization code is the last section. Different separator patterns can be used for even finer resolution. Typical separator lines are identical-length comment lines full of -, =, #, *, or other symbols.
Summary of the code
This type of comment summarizes how the code works. It allows someone not familiar or interested in the details to scan through quickly. This type of comment is usually placed before a block of instructions, or before a local subroutine. As programs grow in length this comment can become more and more important.
Description of the code's intent
Description comments tell us how to use a subroutine or a component. The comment is usually placed before subroutines, before objects, and at the beginning of the file or section. A well-written description of a subroutine does not bother us by telling how the subroutine works, it only lists the input and output parameters, gives a short description of the function and possible side effects. A more detailed explanation can be given in a help file, as is often the case with components, global objects and global subroutines.
Common questions
When shall I write comments?
While writing the program! It is wrong to wait until the completion of the code. Comments can help while writing the program. And you may forget to write them in the end, or worse yet, forget how some tricky part worked. Even writing summary information and copyright messages after the project is finished is not a good practice. You know who the copyright holder is right from the beginning -- why not start the file with it?
How shall I write comments?
The main rule is to write the comment in a way that does not interfere with the reading and maintenance of the code. Writing separate comment lines before each line is unnecessary, and makes the program unwieldy and difficult to follow. The best place for comments is at the beginning of a subroutine, block of code, or object definition. If you keep subroutines short, there is little need for anything else. Endline comments are also useful to explain the intent of the code. I start endline comments at position 81. This allows me to read the code and the comments separately, or read the code only and refer to the comments only for clarification. Using XGA resolution and 8 point size letters about 120 characters/line is manageable and printable. Position 80 is almost always enough for the code, and the 40-character length is not too great a restriction on endline comments. I prefer longer lines to using abbreviations. Endline comments should give information that is not obvious from the code. If you have nothing to add then don't.
Example
A freeware program written for publication
Multi-glyph controls components are my freeware components, which I have written for publication with the intention that they might be useful for learning advanced programming skills. There are plenty of comments in the source explaining everything not obvious, but most of the information for component users is provided in the help file. The readme file gives detailed installation instructions, and contains the usual copyright and licensing information.
I included the source of the help file to encourage programmers to create their own help files, and tried to make it appear almost identical to Delphi help pages.
Two HTML pages are based on this component package. One describes the component, the other gives information about generating help files that integrate seamlessly into the Delphi Open Help system. The first is mostly repeated in the enclosed readme file and help file, while the second is maintained separately and references the component only as an example of creating help files.
Written by Pinter Gabor
H-8000, HUNGARY
Tel: +36 30 9972445, Fax: +36 22 304326