Code Comments

How many time have I heard a programmer say: “If the code is written well enough, there’s no need for comments”. This statement could not be farther from the truth. The code, sans comments, obviously defines the what and how: what does the code do and how does it do it. But what is missing from this is the why: under what conditions and what assumptions were made.

Comment Types and Categories

Before discussing commenting practices let’s break down the various types of comments. Some of these are specific to Java and javadoc but it should be an easy exercise for the reader to extrapolate to other langauges.

  • File comment: a comment at the top (or just below the package statement) of each file that typically contains the name of the file, the date it was created and any copyright or license information for that file.
  • Type comment: a comment for the type or class that contains the purpose and functionality as well as any global information about the class.
  • Member (method or field) comment: a comment for each field and method of a class. All member comments will contain a description of its use. For methods, expected and allowed argument values as well as any expcetions that are thrown are listed. For fields, value ranges and expected or not allowed values are listed.
  • Block comment: a comment before an algorithm or section of code elaborating on its use. A block comment may contain only a single line. (This definition varies from what is traditionally used.)
  • Inline comment: a comment contained on the same line as a program statement typically used to describe the need for or use of that statement.
  • Exclusion comment: a comment delineating a section of code that is not to be executed. (This is typically called “commented out code”.)

These comment types can be divided into categories:

  • For using the code / API: These comments assume that the code will not be present. Type and member comments are in this category and are typically contained in javadoc-style comments.
  • For maintainers of the code: The code is present but a greater understanding of the code is necessary. Block and inline comments are for maintainers of the code.
  • For Housekeeping: File and exclusion comments and portions of the type comments contain information that is used purely as meta-data for the code.

Commenting Guildelines

  • Commenting is not an after thought. Commenting should occur before each code block is written. All functionality, potential limits and problems should be completely described before the code is written. There should be no surprises when you actually begin coding a block. All functionality should be understood and described in the comment before the code is written.
  • Comments are in part for you, but are most commonly used by others. Ensure that the content and style are such that someone who has never seen the code before understands the “why”s of the code. Have some compassion for the poor clod that has to maintain the code … because that poor clod may be you in tweleve months!
  • Work from the outside in. When creating a new class, begin by explaining the function of the class and why it is needed (and, for example, why another class wasn’t used in its place). For each member field and method added, descibe its function clearly and concisely as well as its reason for being. Given that javadoc comments are used to produce API documentation, limit the explaination of the internal functioning of the method in the comment. Having such verbosity tends to confuse readers who simply want to use the function. Save the verbose description for inside the method itself.
  • Comments should be written as if you are new to the code. Do not assume anything. Attempt to reference the reader to as much pertinent information as possible.
  • It is more important to explain the “why”s rather than the “what”s or “how”s Most often, the “what”s and “how”s can be determined from the code itself, but the “why”‘s can never be derived. Each decision that is made and the reasons for it, should be explained clearly and concisely in comments. Refer to the entry What about the “Why”? for more information.
  • Comments should be clear and concise. You’re not writing War and Peace and you’re not going to win a Pulitzer for your work.
  • Try to limit replication of comments, but also remember that you do not know where and how another developer will begin looking at the code. Use “see <other>” to inform the developer where to go for related information or use roll-up documentation such as the package.html file.
  • Keep the language to 3rd person as much as possible. Other developers, many times removed, will not know who “I” or “we” are. If “I” is necessary for describing a “why”, include your initials to give some context and make sure that you have been added to the author list of the file. For example, “(RG)”.
  • Always keep comments up to date. If a comment described undesired functionality and that functionality is reparied, leaving the comment in place will cause loss of productivity while another developer attempts to understand the “problem” and fix it. Always check the code to ensure that any changes are reflected in the comments. It does not need to be commented that the problem was fixed (that is what version control is for). Simply remove comments that no longer apply and replace with comments describing the new or changed functionality.
  • Perform a code walk-through of your own code before you submit it. You should be able to read the comments and understand completely what (and why!) the code is doing without ever reading a single line of code. Then, ensure that the code matches the comments exactly.
  • Exclusion comments must have an accompanying explanation and that comment must be added at the time when the exclusion is made. The number of times that a section of code is commented out for debugging purposes only to be checked in in that state is staggering. Unless there is a comment associated with the exclusion, there is no way to distinguish if that code is broken, unneeded, an example, or removed for debugging.
  • Before each logical block of code, there should exist a block comment completely describing the code section. Inline comments are used to describe the action or reason for a particular line. For example:

    int size = array.length;        // purely a convenience variable
    
  • Clearly state expected, allowed and disallowed values as well as scope for fields.

    /**
    * The user of the application.  This value is only allowed to be null
    * between construction and when the value is set (via
    * {@link #setUser(User)}).  If null when used an exception should
    * be thrown.  This value may only be set once and if reset an
    * exception should be thrown.
    */
    private User user;
    
  • Comment all non-explicit else or default statements. Because a significant number of bugs are the result of not understanding the implication of an else or default, the extra time spent thinking though them and commenting them are time well spent. For more information, refer to the entry: Coding Defensively.
  • Comments are not editorials. Be professional and refrain from writing editorials.

Comment Notifiers

It is common to see XXX or FIXME in code. But there are more notifiers that can be used:

  • NOTE describes a situation which is not obvious from reading the code directly but is desired behavior or describes assumptions or constraints that are not explicit.

    Ex: “NOTE: this will not work with values less than zero.”
    Ex: “NOTE: this function was added as a work around for the bug found “
  • FIXME denotes code that simply does not work. Describe the symptoms or whatis broken.

    Ex: “FIXME: values greater that 10 cause this function to fail.”

  • TODO describes functionality that still needs to be added or describes code that performs a function, but work still needs to be done.

    Ex: “TODO: multi-auth is not implemented”

  • CHECK describes functionality that at initial overview does not appear to be correct but does perform the necessary function.

    Ex: “CHECK: can ‘j’ be less than zero here?”

  • BUG followed by an identifier marks a section of code that is in place or has been fixed because of a bug report.

    Ex: “BUG #8452: the value much be checked for null before using”

  • REQ followed by an identifier is a reference to the requirements documentation.

    Ex: “REQ 5.7.1a: non-logged in users are not allowed”

  • PERF is essentially a NOTE but is specific to a performance optimization. For all intents and purposes NOTE can be used in its place.

  • Ex: “PERF: ArrayList is explicitly used (rather than List) to minimize the overhead of polymorphism”

At times the modifiers can be ambiguous; a CHECK may represent a FIXME that needs to be TODO‘ed and NOTE‘ed. It is always better to use a more severe marker such as FIXME rather than CHECK for tracking purposes.

Advertisements

3 comments

  1. I tried to make this document more of a set of general guidelines than language-specific practices. Unfortunately I’m not an ASP .Net guy so I can’t help explicitly. Try whipping up some examples and posting them and we can work through them if you’d like. (I don’t know how well that they will turn out though with the crappy formatting of this blog’s comments.)
    Take care and thanks for commenting!

  2. Pingback: More on Code Comments « rgrzywinski


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s