Child pages
  • Documentation Guidelines
Skip to end of metadata
Go to start of metadata

This page contains a collection of suggestions for what to think about when writing code-level documentation. The documentation in code falls into two categories, described in separate sections below.

Interface documentation

Interface documentation consists of the header comments for files, classes, and methods. Its purpose is to support abstraction: the creation of reusable modules with simple interfaces that hide complex internals. It should be much easier to use a module than to understand its implementation. The module's documentation describes its interface.

  • Interface documentation should be as simple and short as possible, while still providing all the information needed to use the underlying code. If it becomes long and complicated, it suggests that the module may not have a clean interface, so perhaps you should consider redesigning the module.
  • The purpose of interface documentation is to describe how to use a module. It should not describe the internals of the module (if knowledge of the internals is needed to use a module, it suggests that the module doesn't represent a very clean structure). For methods, no implementation documentation should appear in the method header: put it in the body instead.
  • In writing interface documentation, think about the contract between the module and its users; anything that affects this contract should be documented. One example is ownership of memory: if methods in the module return dynamically allocated memory, who is responsible for eventually freeing the memory? Exceptions are another example.
  • Interface documentation should describe not just "what" but also "why". "What" means information such as parameter descriptions, return values, and side effects. "Why" means information such as why this class is needed: what problems does it solve, and in what situations will this class be used? For methods it's often useful to document the situations under which a particular method should/will be invoked (this is particularly useful for callback methods, which are invoked automatically in response to external events).
  • For methods, be sure to document side effects, which consist of any ways this method could affect the future operation of the system, other than through value(s) returned to the caller.
  • In the documentation for a method, use different words from those in the method's name. For example, for a method flushBuffer don't say "Flush the buffer" in the documentation, since that provides no new information. Instead, say something different like "Write the buffer contents to the underlying network connection". This second form also indicates when someone might want to call this method.

Implementation documentation

These comments are intended to help developers understand how code works internally. It includes documentation in the bodies of methods plus documentation of member variables in classes, which are usually private.

  • Don't repeat what is obvious from the code. Believe it or not, code like the following happens a lot:

    // Increment i
    i++;
    
  • Document things that are not obvious from the code, perhaps at a higher level. For example, you might include a short comment before each loop that indicates what each iteration of the loop corresponds to, and, at a high level, what each iteration does:

    // Each iteration of the following loop processes one page, writing it
    // to swapping store if it is dirty.
    for {...} {
    ...
    }
    

Overall suggestions

The following suggestions apply to both implementation and interface documentation.

  • Be precise. Just a couple of extra words can often make things dramatically clearer. For example, "Address of the first byte to be copied" is more precise than "Source buffer".
  • Give units. For example, say "Number of bytes to copy" instead of "Buffer length".
  • In general, it isn't the quantity of documentation that matters as much as the quality. A few carefully crafted sentences can be more useful than a page of rambling text.
  • Try to abstract out the overall ideas and concepts in the code being documented. Is there something you can say in just a few words that will create a mental model that makes it easy for someone to use or understand the code?

Other questions

What about private methods within a class: should they be documented like "implementation"?

Ideally, even private methods should provide encapsulation in the sense of hiding some nasty detail from the rest of the class. In this case, they should be documented in a fashion similar to public methods to reflect this abstraction.

On the other other hand, there will be some cases where there isn't much abstraction in a private method; it's just a way of sharing code between other methods. In this case the private method is just a shared implementation detail, so it's okay for the method header to be somewhat more abbreviated, for example:

    This method is used internally in several places to perform
    the main body of work in copying data out of a Buffer.

Even in this case parameters and result should be documented (but if it's hard to explain them outside the context of the calling method it's okay to keep the documentation brief and vague).

This second case as a necessary evil that we tolerate in situations where it's the best available alternative, but it's better if private methods can fall into the first category where they really have abstraction and the documentation reflects it.

  • No labels