Packetizer Logo
 

Writing Code for the Next Person

By: Paul E. Jones

Function Description

One of the biggest areas of efficiency improvement is in having clear function descriptions. This avoids the need for one to read through an entire function to understand why it exists or how to use it. As with file descriptions, I have a template I use for describing functions.

Source Code

/*
 *  FUNCTION()
 *
 *  Description:
 *      DESCRIPTION
 *
 *  Parameters:
 *      None.
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
 *      None.
 */

I will briefly describe each section:

  • Function: The name of the function, including a class name if the function is the member of a class.
  • Description: Human-readable text that explains the purpose of the function. This should provide enough detail that the reader does not have to "read the code" in order to know what the function does.
  • Parameters: Enumerates all of the parameters to the function, indicating if they are for input, output, or both. This should contain a short description of each parameter.
  • Returns: Describes what is returned from the function, including a return value and output parameters. It should also describe any error cases the user should consider.
  • Comments: Any additional commentary to ensure the function is used properly. As an example, if there are any preconditions that need to be met (e.g., having a mutex locked), that would be described here. Also, this section would be used to describe any side effects that are not necessarily obvious.

The following is a real example from an AES library that performs encryption on a block of data.

Source Code

/*
 *  AES::Encrypt()
 *
 *  Description:
 *      This function will encrypt a block of plaintext and return the
 *      ciphertext.
 *
 *  Parameters:
 *      plaintext [in]
 *          The 16-octet data block to encrypt.
 *
 *      ciphertext [out]
 *          The 16-octet encrypted data block.  AES operates in place, so this
 *          span may be the same memory location as the plaintext span.
 *
 *  Returns:
 *      Nothing, though the encrypted data is stored in the ciphertext
 *      parameter as output.
 *
 *  Comments:
 *      None.
 */

While that is a trivial example, it nonetheless demonstrates how I document code I write. Generally, I place this kind of description only in the source code files (e.g., .c or .cpp), as opposed to header files (e.g., .h). However, for those writing libraries to be distributed to third parties where the source code is not provided, you can see how this kind of documentation might also be useful in header files, too.

This is a format that I follow, but it is not the only style one might consider using. Some people — especially those working on open source projects — use a format prescribed by the tool Doxygen.

The following is an example using the Doxygen syntax.

Source Code

/**
 * @brief Encrypt a block of plaintext and return the ciphertext.
 *
 * This function will encrypt a block of plaintext and return the
 * ciphertext.
 *
 * @param plaintext The 16-octet data block to encrypt.
 * @param ciphertext The 16-octet encrypted data block. AES operates in place,
 *                   so this span may be the same memory location as the
                     plaintext span.
 * @return Nothing, though the encrypted data is stored in the ciphertext
 *         parameter as output.
 *
 * @note None.
 */

This is a fine format, but the reason I do not personally use it or recommend it is that commentary in the code is designed for humans to read. Doxygen, on the other hand, is designed for a computer program to read and transform into a human-readable HTML page. By a wide margin, teams working on code are going to be staring at comments in the code more than a separate document. For that reason, I prefer to use a style that is friendlier for human consumption.

Additionally, one could transform the human-readable form into an HTML page, too. The function name is consistently placed, as each section. Details within each section are consistently indented. I do sometimes add addition sections if it makes sense, but those shown are the standard sections I define for all functions. (I've never had a need to produce HTML documentation, though.)

One additional note about this particular example is that the function description explains that the output buffer can be the same as the input buffer. This information can substantially improve performance in some cases and is a good example of the kind of information that should exist in a function description. In the code from which this example was taken, one would have to wade through a lot of source code to otherwise figure this out.