Documenting Code with Doxygen
My last post, quite a while ago, expressed my preference for putting usage comments (as opposed to implementation comments), as far as possible, in header files on the grounds that the header file is the primary interface which the user has with the code. The code file (.c or .cpp), from a user’s perspective, contains a lot of irrelevant text and may not even be available for inspection in any case.
I did, however, write:
I’ve used several approaches but I’ve yet to settle on a “best” one. Indeed, the concept of “best” hinges to some extent on the approach, if any, taken with regard to external code documentation
Doxygen is perhaps the most popular open source tool for producing extensive, structured, external documentation by extracting comments (which have some special formatting) from the source files. As it can extract from both header and code files, the question is re-opened as to where it is best to put the usage comments.
Once the Doxygen output is available for users to read, those users no longer need to read the header files to understand the API. So to whom might the original comments now be most useful? My answer would be the maintainer of the code. Yes, the maintainer, not the original developer, who knows the code intimately anyway and tends – rightly or wrongly – to put in the usage comments only after most of the code has been written. It is important for the usage comments to be easily accessible to a maintainer, to help ensure that the original user interface (the API) and purpose of the module(s) are not accidentally subverted during code modifications.
Certainly a maintainer will have occasion to edit header files but most of his or her time will be spent working with the code files. Therefore, if (and only if) external user documentation is available, from a tool like Doxygen, my previous recommendation is more or less turned on its head:
- Put as many as possible of the formatted usage comments in the code file (if there is one). The documented items would typically include most functions and static variables, whether class members or not.
- Put the rest of the usage comments in the header file, such as those for most classes and their non-static member variables, certain typedefs and enumerations and all inline functions (or all member functions in the case of templates). I would still recommend that function definitions (inline and/or template functions) should be redeclared outside (i.e. below) the class declaration and documented there, to avoid cluttering the class declaration.
Next time I will turn my thoughts to documenting via UML tools.