Commenting Code Interfaces
What Are Code Interfaces?
“Code interfaces” is a term used here to refer to any kind of code that another programmer might need to understand and “interface with” when working on code.
It doesn’t just mean “public interfaces” that would exist in a released library or API - when maintaining code, all levels of “interfaces” (even internal/private ones) are important to understand. Such interfaces can include namespaces/packages, files/modules, data types, functions, variables, or potentially other things.
Any “symbol” in code that another programmer might have to use (or maintain) is important enough to understand and thus likely warrants being commented. Making sure the interfaces to that code are well-documented is important for team productivity and success.
There are some places where some of this documentation may seem overly obvious/redundant. We’ll also cover some techniques that can help minimize this and aid in comment maintainability.
Documentation Styles & Generators
Documenting code interfaces is often covered by many coding standards, which may mandate specific styles.
However, many styles are supported by various common documentation generators. Documentation generators tend to provide the following benefits:
A standardized format for many kinds of documentation: A consistent format saves time by reducing the time needed for people to decide on a documentation style or interpret someone else’s format. The consistency helps teams of programmers focus more on the more valuable documentation content.
The ability to generate web-browsable documentation: Documentation generators can extract comments from the code itself and generate HTML documentation that can be navigated in a web browser. This can be particularly valuable for code that serves as a public API/library.
Automated checks for incorrect documentation: Due to the more free-form nature of documentation, documentation generators can’t warn about everything that may be wrong in documentation. But many documentation generators warn for things like missing parameter or return value documentation, providing some automatic safety net in keeping documentation up-to-date.
Some common documentation styles/generators include:
Doxygen (multiple languages)
Javadoc (Java)
Python docstrings (Python)
Napoleon-style docstrings (Python)
Sphinx (multiple languages)
JSDoc (JavaScript)
This training will leverage some of these common formats in examples. But the specifics of a style are less important than the content of the documentation. So if you have a different style, the guidance outlined here should be transferrable to your style.
Python documentation styles in particular can widely vary, and getting a particular style to work right can depend on specific configuration. With such wide variety, it’s hard to cover every single Python documentation style in every example. This training will aim to cover 3 common yet fairly different styles - Doxygen, Sphinx reST docstrings, and Google-style docstrings - at least in examples for function documentation.
For other examples, documentation may be restricted to one style (often Doxygen-style, since that tends to be most concise for code examples). However, outside of functions, there are fewer specific “tags.” so it’s mainly the core content of the comments that comes into play. The content of the comments should be easily transferrable to other styles, so check coding standards your organization has adopted.
Essential Tags for Common Documentation Generators
Most documentation generators leverage specific “tags” that can be inserted into comments to identify the specific kind of entity in code being documented - parameters, return values, etc.. This structured format is how documentation generators can understand and parse comments correctly.
The following are some essential tags across several common documentation generators:
Purpose | Doxygen | C# XML | Javadoc | Sphinx | JSDoc |
|---|---|---|---|---|---|
Overall description |
*Though typically no-longer needed. |
| N/A | N/A |
*Though typically not needed. |
Parameter |
|
|
|
|
|
Return Value |
|
|
|
|
|
Exception |
|
|
|
|
|
Putting it All Together - An Example
The following example demonstrates how many of the techniques described in this section can come together using some documentation-generator styles mentioned above:
Documenting Different Types of Code Interfaces
Different types of code interfaces can have specific considerations. The sections linked to below give tips on documenting different common types of interfaces:
- Namespaces/Packages
- Files/Modules
- Data Types
- Functions
- Order Documentation to Support Function Usage [DI14]
- Giving an Overview of a Function
- Documenting Parameters
- Documenting Return Values [DI21] [WHAT]
- Documenting Exceptions [DI22] [WHAT]
- Documenting Function-Like Macros [DI23] [WHAT] [WHY] [HOW]
- Document Why C++ Special Member Functions Are Deleted [DI24] [WHY]
- Variables
- Documenting Variables Based on Scope
- Documenting Specific Kinds of Data
- Documenting Constants [DI27] [WHAT]
- Make Meanings of Booleans Clear [DI28] [WHAT]
- Document the Meanings of “Unpopulated” Values [DI29] [WHAT]
- Document Values with Special Meanings [DI30] [WHAT] [WHY] [HOW]
- Document Ranges of Numeric Values [DI31] [WHAT] [WHY] [HOW]
- Document Units of Numeric Data [DI32] [WHAT]
- Document Data Formats That Cannot Be Concisely Captured in Names [DI33] [WHAT] [HOW]
- Document Specifics of Filesystem Paths [DI34] [WHAT]
- Document Time Zones for Dates/Times [DI35] [WHAT]
- Document Bit-Level Details For Packed Data [DI36] [WHAT] [HOW]