How to properly comment

11,584

Solution 1

C files should contain the usual comments you write anywhere when you write code. What does it do and why. Usually at the end of each line unless there is a need for more extensive comments.

H files can either contain a brief minimum, explaining what a function takes as parameters and what it returns. Or alternatively it could contain a full documentation of how the function should be used. If the full documentation is not provided in the header file, you will have to write it separately. Note: a few lines of Doxygen crap just to generate some manner of useless "documentation" file does not count as complete documentation.

H files document what a function does and how it should be used, without mentioning implementation details. It is important is to realize that a h file should be the full, stand-alone interface for the corresponding c file (or library). All types and dependencies (includes) that the caller needs to be aware of should be present in the h file.

This includes any pre- and post-conditions: What needs to be executed prior to calling a function? What resources did the function use? Did it leave any handles/files/resources open that need to be cleaned up later? Did it alter some global state? Etc etc.

The corresponding c file(s) are not necessarily made available to the user, nor should the user need to read the c file in order to understand how the functions there should be used. Everything should be made obvious from the h file alone.

Solution 2

Personally, my rule of thumb is to simply avoid comments if at all possible.

To do this, as much as possible;

  • Make declarations in headers self-documenting by appropriate choice of type names, constants, enumerated values, function names, variable names, etc;
  • Make function definitions as small and simple as possible, to make it as clear as possible how they do their thing. Make the functions as self-documenting as possible by appropriate choice of variable names, local types, etc etc. Break big functions into a set of smaller functions, and make ALL of the functions as self-documenting as possible.
  • Choose filenames (for headers and compilation units) so groupings of functions and declarations is obvious.

Then use comments only when needed to explain something that isn't obvious by looking at the code itself. For example, it is better to explain WHY code does something, and allow the HOW to be described by the code itself. If a function has particular preconditions (things assumed to be true when it is called) or post conditions (things the function guarantees to be true when it returns if the preconditions are met) then those can be described in comments.

I don't use comments for things like tracking version history (that's what version control systems are for).

Sometimes it is impossible to write code in a way that is simple and obvious. In those cases, comments are needed. But the problems with comments (e.g. forgetting to update them, so they no longer correspond with the code) are so significant, it is better to work hard so the code - without comments - describes itself as well as possible.

This also means working hard to avoid cryptic code. Don't write statements with 25 side effects. Indent code so it is consistent with actual structure (code formatters can help with this). Avoid macros (since they can do things inconsistent with scope) as much as possible.

Share:
11,584
Badda
Author by

Badda

Student in computer science so far. Wishing to help as much (or even more) as I have been helped.

Updated on June 04, 2022

Comments

  • Badda
    Badda almost 2 years

    This is a very simple question which I am surprised I haven't found anywhere else on SO. I was wondering which comments should or shall not be in header/source files and even, because some languages don't really use the header/source system, what is the proper way to comment.

    So far I have been doing it like that :

    main.c or main.cpp

    int main()
    {
        // Comments to describe what happens in main
    }
    

    foo.h

     // Comments for documentation and which gives information about the function itself
    
    /**
    * \fn void aFunction(void)
    * \brief This function is a function
    */
    void aFunction(void);
    

    foo.c or foo.cpp

    void aFunction(void)
    {
        // Comments to describe and explain what happens within this function
    }
    
    • Not much comments in main, just describing basically what functions are called and why
    • In header, only comments to describe the function itself; parameters, brief, return etc.
    • In source, only comments to describe what's happening within the function; loops, condition, etc.

    That is what I know for sure. Are there more comments needed in either main, source or header ? Should I add the comments I usually only put in the header in the source too, like that :

    foo.c or foo.cpp

    /**
    * \fn void aFunction(void)
    * \brief This function is a function
    */
    void aFunction(void)
    {
        // Comments to describe and explain what happens within this function
    }
    

    I know this may sound subjective, but it is an obvious fact that some devs are better at commenting than others, and thus that there are good and bad ways to comment.

  • Lundin
    Lundin almost 7 years
    Regarding version history, I tend to use both a summary on top of the file as well as version control. Because code often ends up outside your company, for various reasons. But I agree that detailed comments like // Changed 170516 by Bob should be avoided.
  • Badda
    Badda almost 7 years
    "All types and dependencies (includes) that the caller needs to be aware of should be present in the h file." I get that all includes need to be done in the H files, is there something else ? Do you for example comment some includes to explain why you used them and what they do ?
  • Badda
    Badda almost 7 years
    This answer has been as much useful as the accepted one; focusing on how to avoid commenting seems at least as important as knowing what and where to comment. Thanks
  • Lundin
    Lundin almost 7 years
    @Badda It is enough to list all included headers. This gives the user information about dependencies and what files that will be needed to compile the code.
  • Jon
    Jon almost 6 years
    While I cannot find fault with your argument of writing code well, I do take one point to raise: Code -should- be liberally commented, because, while a function may be commented "do the thing", the HOW of what that function is doing may not be obvious - algorithms, funky bitshifts (aka Coder "Cleverness"), data copies... sometimes, the HOW is a mess ("Why is this data being copied there?" "Why is this compared to that value?" "Why is this result not valid here but valid there?") Coders need to explain their work so that others don't have to endure the "right of passage".
  • Peter
    Peter almost 6 years
    @Jon - You say that comments need to describe the HOW, but the examples you cite to justify that claim are all examples of describing the WHY ("Why is this ...?"). I've already said that comments should focus on the WHY.
  • Abdel Aleem
    Abdel Aleem over 3 years
    One school of thought argues that in C-files the code should be written in a way that makes it self-explanatory (i.e. the code becomes the documentation). Comments should only be added to further elucidate something that cannot be deduced from reading the actual code.
  • Lundin
    Lundin over 3 years
    @AbdelAleem Yes you can write self-explanatory code to some extent. But it doesn't apply in the above case - you should not document what a function does with that function's implementation. One of the main reasons of having a function to begin with, is that the caller shouldn't need to worry about that function's internals. Except perhaps internal linkage functions that aren't part of the module's API.
  • bjaastad_e
    bjaastad_e over 3 years
    I'm integrating with the V8 JavaScript engine now, and I think it's beautifully commented in the header file. It does not shy away from using many words to describe the intentions behind a function or a class. I think it hits the balance just right! github.com/v8/v8/blob/4b9b23521e6fd42373ebbcb20ebe03bf445494‌​f9/…
  • Abdel Aleem
    Abdel Aleem over 3 years
    @Lundin I understand your point. But the self-explanatory part of a function wouldn't be the function implementation itself, but rather the function name.