Doxygen Cargo Cult
Stop writing comments that duplicate the actual code, stop stating the obvious.
For any practice, we need to understand why we are doing it and recognize that there is a value in doing it. If we follow a practice without understanding it, we may not be getting the intended value out of it.
Some developers seem to think it is essential to document every class or function with a comment, which can look like this:
/*! \brief Sets the enabled flag
*
* @param bool enabled value to set the enabled flag to
* @return
*/
void setEnabled(bool enabled);
The comment duplicates the code, it communicates the same information to the reader as the code itself does. Repetition does not make the interface easier to understand. Worse, it pollutes the code with redundant noise.
Unfortunately some developers are placing comments like this everywhere, without considering if their comments add any value at all. I think when they see a few functions decorated with comments, perhaps even useful comments, they are led to believe that these comments are supposed to be on every function.
If there is no value gained from adding a comment because the function signature is trivial to understand, but someone still does it, it is a prime example of Cargo Cult Programming. They ritualistically add comments to interfaces, without understanding that documentation is meant to provide additional information, not able to be expressed by the code itself.
Sometimes a comment actually makes it harder to understand. Perhaps the code changes, but the comment was not maintained to reflect the new code.
Perhaps the comment was copied to/from another function to be used as template (e.g. the Doxygen format), but forgotten to be adapted to match the new code it is documenting.
I have seen it many times. Out of date comments. Copy-paste errors. It is unfortunately so common, that I consider it best practice to avoid comments almost all together, since they tend to do more harm than good.
A comment is an invitation for refactoring
The slightest divergence between code and comment can create serious confusion. Consider this example:
// Returns boolean flag that indicates whether the device is allowed to be used.
bool isDeviceUsed(DeviceId deviceId);
Do you know what true
being returned represents?
- It means the device can be used
- It means the device is being used
These are not the same.
The developer went through the extra effort of trying to clarify the meaning of their function. Unfortunately, it only raises more questions due to a subtle difference between the function name and the comment. We cannot know whether the comment is incorrect or the function name is incorrect, by only looking at the declaration of this interface.
If only there were a single source of truth, in the form of a function name.
Since the function name will be visible at any client code using this function, it is much more valuable to have a clear and descriptive function name rather than a clear and descriptive comment.
See also c2.com#CommentCostsAndBenefits