views:

577

answers:

6

Is there an accepted best practice for commenting functions? I only know of the doxygen style but it is not officially supported by C++ like Javadocs is for Java so just wondering what is best.

+1  A: 

I think there is no such thing as the "best" style. You should use the one that works for you. It varies heavily based on the purpose of the code. Public library APIs need such comments the most. On the other hand, private methods of implementation classes may probably rely on just being self-documenting, as no comments is usually better than wrong/obsolete comments.

By the way, Doxygen supports several styles, Javadoc being one of them.

Alex Jenter
+4  A: 

Nothing will be "officially" supported because there's no company behind C++.

As you can see, doxygen support a lot of different blocks http://www.doxygen.nl/docblocks.html

I personnaly prefer to stay close to other other reccomandations. I try to stay near javadoc best practices.

X-Blaster
+1  A: 

There are number of advice for commenting, so much so that it has an entire chapter in Code Complete. Do note that Javadocs and Doxygen style are also catering to automatic generation of documentation in mind. What they encouraged is usually fine.

Some advice which I find important are:

  1. Comments should describe why, not what you are doing

  2. Comments should be in a form easy to maintain and type out. No fanciful ascii header and art please!

Extrakun
A: 

You can follow the Google Style for commenting.

Types of things to mention in comments at the function declaration:

  • What the inputs and outputs are.
  • For class member functions: whether the object remembers reference arguments beyond the duration of the method call, and whether it will free them or not.
  • If the function allocates memory that the caller must free.
  • Whether any of the arguments can be NULL.

  • If there are any performance implications of how a function is used.

  • If the function is re-entrant. What are its synchronization assumptions?

codaddict
Google Style reflects their `C` orientation. In `C++`, if an argument cannot be `NULL` it ought to be a reference and memory ownership can be expressed semantically with smart pointers. I would refrain from referring to Google's way of coding... they are in their own world.
Matthieu M.
+9  A: 

There only general thing most people will agree with is that comments should say "why", not "what". Other than that, guidelines depend on the coding standards at your place of work.

Personally, I hate doxygen and the like, because it contradicts the first thing I said. The "documentation", if it can be called that, is just a prettified header file. And the cost? Nearly duplicated code, obtrusive comments (seriously, it doubles the height of everything), and just a pain.

Your code should be self-documenting: use descriptive names, factor everything into well-defined tasks, etc. The only comments should be things that may need clarification.

For example, an excerpt from a network socket class I wrote:

const bool socket_connected(void) const;

You already know what this function does; I don't need to explain it. Do I really need to add a big chunk of comment explaining that it returns a boolean (duh) that will indicate of the socket is connected (duh)? No. doxygen is just going to take my header and add some fancy style-sheet to it.

Here's an example where a quick note may be useful (making this class up):

struct fancy_pants
{
    // doesn't transfer ownship, ensure foo stays alive
    fancy_pants(foo&);
};

Now it's clear I need to make sure the foo I pass it doesn't go out of scope. This didn't require the uglification of my code. If I'm going to write documentation, it should be written by me, describing rationale, intended usage, "gotcha"'s , examples, etc. Like Boost.

That said, all my headers have a copyright block on the top. I find this is a fantastic place to write a tiny bit of info about the class. For example, is_same.hpp:

/*-------------------------------------------------------
                    <copyright notice>

Determine if two types are the same. Example:

template <typename T, typename U>
void do_something(const T&, const U&, bool flag);

template <typename T, typename U>
void do_something(const T& t, const U& u)
{
    do_something(t, u, is_same<T,U>::value);
}

---------------------------------------------------------*/

It gives a quick demo at a glance. Anything more, like what I said above, is in a written documentation file.

But you see, I get to make up my code standards for the most part. At companies, you usually have to follow their standard anyway.

GMan
</rant​​​​​​​​>
GMan
I totally agree! I changed my view on doc comments when realized most of them didn't give any useful information and were evident from the code. I even encountered comments like "This is class X that implements the IX interface". And I'm not making this up.
Alex Jenter
@Alex: I believe you; that's what the comment style requires. And ack, I've been down-voted; but that's expected. :P
GMan
I hate putting the documentation into an documentation file. This means I have two documents that I have to keep in sync. Documenting the interface in the header using doxygen style is one of the best things I ever started. So the documentation is extracted from the source code.
Totonga
@Totonga: but then, if you are asked to "augment" the documentation, then you modify the header... oh sweet recompiling. And the problem with doxygen comments is that they are useless much of the times: **I** don't have to read a comment to know what are the types and names of the different parameters and the return... So what's the point using up 5-6 lines in comments ? It only wastes valuable screen estate. And don't get me started on memory ownership, if I pass a raw pointer, I don't expect you to delete it, that's my pointer goddammit.
Matthieu M.
@Matthieu: Doxygen doesn't force you to document the parameter/return types and names - it can read these from the code, and you only need to add comments if anything that needs commenting. Of course, that doesn't stop people adding pointless boilerplate comments, but they'll do that with or without doxygen.
Mike Seymour
@Mike: I agree, I guess it stems from 'comments' metric...
Matthieu M.
A: 

From http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Comment_Style

You can use either the // or the /* */ syntax; however, // is much more common. Be consistent with how you comment and what style you use where.

// Iterates over the contents of a GargantuanTable.  Sample usage:
//    GargantuanTable_Iterator* iter = table->NewIterator();
//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
//      process(iter->key(), iter->value());
//    }
//    delete iter;
class GargantuanTable_Iterator {
  ...
};

Another example:

// Returns an iterator for this table.  It is the client's
// responsibility to delete the iterator when it is done with it,
// and it must not use the iterator once the GargantuanTable object
// on which the iterator was created has been deleted.
//
// The iterator is initially positioned at the beginning of the table.
//
// This method is equivalent to:
//    Iterator* iter = table->NewIterator();
//    iter->Seek("");
//    return iter;
// If you are going to immediately seek to another place in the
// returned iterator, it will be faster to use NewIterator()
// and avoid the extra seek.
Iterator* GetIterator() const;

Class members:

private:
 // Keeps track of the total number of entries in the table.
 // Used to ensure we do not go over the limit. -1 means
 // that we don't yet know how many entries the table has.
 int num_total_entries_;

In-line comments:

bool success = CalculateSomething(interesting_value,
                                  10,     // Default base value.
                                  false,  // Not the first time we're calling this.
                                  NULL);  // No callback.

And finally TODO/KLUDGE/etc:

// TODO([email protected]): Use a "*" here for concatenation operator.
// TODO(Zeke) change this to use relations.

I tend to agree with the proposals and styles Google supports. Double slashes are 99% of the time enough to explain what something does. The key is to BE CONSISTENT. :)

David Titarenco
Why don't you wrap `Iterator` in an `auto_ptr` or `unique_ptr` ? That would help much more than precising *don't forget to destroy it*...
Matthieu M.