Monday, September 15, 2008

C++ Coding Standard: Header File Contents

Our C++ coding standard provides some easy rules about what does and does not go into a class header file.
  • 3.1. A .hpp must never include an implementation file.
  • 3.2. A .hpp must include every file needed to compile itself.
  • 3.3. A .hpp must not include files not needed to compile itself.
  • 3.4. Class definitions must be preceded by a documentation comment.
  • 3.5. Function declarations must be preceded by a documentation comment.
    • 3.5.1. Document function pre- and postconditions when relevant.
  • 3.6. A .hpp must not declare variables or constants outside the class.
  • 3.7. A header file must not declare functions outside the class.
    • 3.7.1. Exception to 3.7: operators or template specializations may sometimes be declared outside the class.
  • 3.8. A header file must not use "using namespace" directives.
  • 3.9. Any functions declared in the .hpp which are to be inline, must be defined in the .hpp.
By "documentation comment", I mean a javadoc-style comment formatted for Doxygen. At a minimum, this should provide a brief description of the class or function. Even better, for each function precondition, add to the function comment a @pre tag consisting of a C++ boolean expression that can be assert()ed at the beginning of the function. I have an emacs function that scans header files for @pre tags, then locates the function definition in the .cpp file and adds the assert()s -- I'll post it here some rainy day.

The standard seems to insist that everything in your program falls into a C++ class. I would say that is an ideal, but one that no one has yet attained. Still, we can interpret the rules to mean that if a header file defines a class, then it only defines that class. Perhaps there are some functions that don't make sense as member functions, but which have something to do with the class, and you're tempted to declare them in {class}.hpp. Well, don't. They should go into a different header/implementation file pair (and once you take that step, you might find that they really belong in some kind of singleton class).

Rule 3.8 is basic namespace hygiene; rule 3.1 seems like it goes without saying, but unfortunately it doesn't. There's a nifty trick to enforce rule 3.2 at compile time: it will be described in section 4.

Next: .cpp file layout/contents.

No comments: