40

Where is it customary to write the in-code documentation of classes and methods?

Do you write such doc-blocks above the corresponding class/method in the header (.hpp) file, or within the source (.cpp) file?

Is there a widely respected convention for such things? Do most C++ projects do it one way rather than the other?

Or should documentation be written on the two sides (i.e. in the .hpp and the .cpp files), maybe with one short description one one side and a longer one on the other side?

Most importantly, are there any practical considerations that makes it more convenient to write it one way rather than the other way ? (E.g. the use of automatic documentation parsers and generators like Doxygen...)

augustin
  • 14,373
  • 13
  • 66
  • 79

5 Answers5

49

Both:

  • Describe the API design and usage in the header: that's your public interface for clients.
  • Describe the implementation alternatives / issues and decisions in the implementation: that's for yourself - later - and other maintainers/enhancers, even someone reviewing the design as input to some next-gen system years hence.

Comment anything that's not obvious, and nothing that is (unless your documentation tool's too stupid to produce good documentation without).

Avoid putting implementation docs in the headers, as changing the header means makefile timestamp tests will trigger an unnecessary recompilation for client apps that include your header (at least in an enterprise or commercial library environment). For the same reason, aim to keep the header documentation stable and usable - good enough that you don't need to keep updating it as clients complain or ask for examples.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • 3
    Usually, I write my documentation before I write the function definitions. That is, unless there is a typo, having to change the documentation usually implies a change in the function as well, so you have to recompile things anyway. – ereOn Aug 26 '10 at 07:39
  • 2
    @ereOn: I think that @Tony suggestion still holds good: if it is part of the interface it is in the header, if it is an implementation detail (*using container A instead of B for reason X*) then a change in the implementation code requires a change in the implementation doc, but users should not even notice. – David Rodríguez - dribeas Sep 27 '10 at 08:00
  • 2
    "Comment anything that's not obvious (**and nothing that is**[...])." Sound advice. The fewer comments, the better. Unit tests are also a great way to document the usage of an API. – johnsyweb Sep 27 '10 at 08:58
  • **Re-compile should not be used as excuse (so please put doc-comments always in header);** my Editor has "**Save as old**" option/extension, which does simply set modified-date to "2000-1-1" and does "Save" on same file (this works because compiler does only check modified-date, not hash of the file). – Top-Master Aug 30 '22 at 04:21
  • Also, people should not try to keep header short like an outline, the IDEs already have outline-view for that!! (We are not in the Nineties.) – Top-Master Aug 30 '22 at 04:31
  • @Top-Master a "save as old" editor feature isn't a reliable approach, as when to use it is only easily coordinated with one build. Say you have build targets T1 and T2 using a header that goes from content H1 to H2a (a substantive change) to H2b (only comments edited). If T1 and T2 were last built against H1, next you work on T2 and rebuild against H2a, then modify H2a -> H2b using save-as-old: T1 now needs a clean build (easily missed; slow). What if you're working on T2, and - unbeknownst to you - someone else is working on T1? What if you just use save-as-old out of muscle memory? – Tony Delroy Aug 30 '22 at 05:00
  • We develop Projects not single-Targets, when we press the build-button all targets in the project get (re)built, and any other-project has an other-build-folder. – Top-Master Aug 30 '22 at 06:36
  • "What if ... someone else is working on T1?" someone stealing my password and editing same file is out-of-scope of this thread, I mean, else pulling with Git will update modified-date. – Top-Master Aug 30 '22 at 06:39
  • "... use save-as-old out of muscle memory?" Mistakes happen, but only the person making the mistake pays the price (wondering why changes don't apply), and our repository is protected by both "pull-request reviews" and "automated tests". – Top-Master Aug 30 '22 at 06:42
  • @Top-Master Always rebuilding all targets is obviously unnecessarily slow, but whatever. "put doc-comments always in header" breaks with this answer's recommendation to put implementation details in the .cpp, which is not just because of timestamp-triggered rebuilds, but also for localisation with relevant code. If you think you can justify your recommendation, perhaps make your own answer? Feel free to downvote mine if you disagree. – Tony Delroy Aug 30 '22 at 12:11
  • Pressing the build-all-button is 99% faster than waiting hours for complete re-build which any header change would trigger. – Top-Master Aug 30 '22 at 12:38
  • Also, localization means to translate something to another language, like from English to Germany, and that should never happen in header nor source-code (and we have third-party files for those). – Top-Master Aug 30 '22 at 12:39
  • Just saying there are workarounds for header time-stamp-change triggered re-builds (I am happy with my up-vote). – Top-Master Aug 30 '22 at 12:44
  • @Top-Master: "build-all-button is 99% faster than waiting hours for complete re-build which any header change would trigger." - that's why I'm cautious about what comments I put in the headers, per my answer. "localization means to translate" - localisation means different things in different contexts, and in the general case means to keep things together - here API comments and related code in headers, and implementation design/docs and implementation code in .cpps/.ccs/.whatever. FWIW, you'll also see it used to describe keeping variable definitions "near" their point of usage. – Tony Delroy Aug 30 '22 at 12:44
  • Assume we have `main.h` and `main_win.cpp`, `main_linux.cpp`, `main_android.cpp` files; Where do you put implementation related doc-comments? Does the doc-generator even support mixing platform docs? – Top-Master Aug 30 '22 at 12:57
  • *My answer:* use inline/normal comments for implementation related documentation, and **never** doc-comments, we want to help documentation readers to understand the big-picture, **not** to confuse them with implementation details of each platform. – Top-Master Aug 30 '22 at 14:21
15

If you make a library, you typically distribute the compiled library and the header files. This makes it most useful to put documentation in the header files.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
4

Most importantly, are there any practical considerations that makes it more convenient to write it one way rather than the other way ?

Suppose that you want to add a clarification to one of your comments without changing the code. The problem is that your build system will only see that you changed the file, and unnecessarily assume that it needs to be recompiled.

If the comments are in the .cpp file, it will just recompile that one file. If the comments are in the .hpp file, it will recompile every .cpp file that depends on that header. This is a good reason to prefer having your comments in the .cpp files.

(E.g. the use of automatic documentation parsers and generators like Doxygen...)

Doxygen allows you to write your comments either way.

dan04
  • 87,747
  • 23
  • 163
  • 198
  • 1
    RE: *"If the comments are in the .hpp file, it will recompile* ***every*** *.cpp file that depends on that header."* For this reason, some consider this behavior an unfortunate aspect of C++. See [Why does C++ compilation take so long?](http://stackoverflow.com/q/318398/1497596). – DavidRR Apr 08 '15 at 13:22
3

Again, both. As for the public documentation, it is nice to be in the .h with a format extractable with Doxygen, for example, as other commented. I like very much the Perl way of documenting things. The .pl (or .pm) file includes documentation in itself that can be extracted using a tool similar to what Doxygen does for C++ code. Also, Doxygen allows you to create several different pages, that allow you to include user manuals, etc., not just documenting the source code or API. I generally like the idea of a self-contained .h/.hpp file in the philosophy of literate programming.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
2

I personally like documentation in the header files. However, there are some that believe that documentation should be put in the source files. The reason being that when something changes, the documentation is right there reminding you to update it. I somewhat agree, as I personally have forgotten to update the Doxygen comments in the header when I changed something in the source files.

I still prefer the Doxygen comments to be in the header file for aesthetic reasons, and old habits are hard to change. I've tried both and Doxygen offers the flexibility of documenting either in source or header files.

DavidRR
  • 18,291
  • 25
  • 109
  • 191
Dennis Miller
  • 952
  • 1
  • 9
  • 22