C++ – Document Functions in Header or Source File?

cheaders

In languages that distinguish between a "source" and "header" file (mainly C and C++), is it better to document functions in the header file:

(pilfered from CCAN)

/**
 * time_now - return the current time
 *
 * Example:
 *  printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
 */
struct timeval time_now(void);

or in the source file?

(pilfered from PostgreSQL)

/*
 * Convert a UTF-8 character to a Unicode code point.
 * This is a one-character version of pg_utf2wchar_with_len.
 *
 * No error checks here, c must point to a long-enough string.
 */
pg_wchar
utf8_to_unicode(const unsigned char *c)
{
...

Note that some things are defined in the header only, such as structs, macros, and static inline functions. I'm only talking about things that are declared in a header file and defined in a source file.

Here are some arguments I can think of. I am leaning toward documenting in the source file, so my "Pro-header" arguments may be somewhat weak.

Pro-header:

  • The user doesn't need the source code to see the documentation.
    • The source may be inconvenient, or even impossible, to acquire.
    • This keeps interface and implementation further apart.

Pro-source:

  • It makes the header a lot shorter, giving the reader a birds-eye view of the module as a whole.
  • It pairs the documentation of a function with its implementation, making it easier to see that a function does what it says it does.

When answering, please be wary of arguments based on what tools and "modern IDEs" can do. Examples:

  • Pro-header: Code folding can help make commented headers more navigable by hiding the comments.
  • Pro-source: cscope's Find this global definition feature takes you to the source file (where the definition is) rather than the header file (where the declaration is).

I'm not saying don't make such arguments, but bear in mind that not everyone is as comfortable with the tools you use as you are.

Best Answer

My view...

  • Document how to use the function in the header file, or more accurately close to the declaration.

  • Document how the function works (if it's not obvious from the code) in the source file, or more accurately, close to the definition.

For the birds-eye thing in the header, you don't necessarily need the documentation that close - you can document groups of declarations at once.

Broadly speaking, the caller should be interested in errors and exceptions (if only so they can be translated as they propogate through the layers of abstraction) so these should be documented close to the relevant declarations.

Related Topic