What Code Comments are Not For.

I deal a lot with other people’s and legacy code.  One of the things I see very often is what I call "misuse of code comments".  Let me provide an exhaustive list of what code comments are for:

  • Describing why code isn’t doing something obvious

There, done.

What code comments are not for (not complete):

The Obvious


// set the value of i
i = value;

It’s obvious that the code is doing that; the comment adds no value here.  The compiler provides no validation that the "i" in the comment really applies to any variable in the line the comment applies to.  Nor does it even know what line the comment applies to!  Comments like this actually introduce some technical debt because I can refactor this code to move it around independently of the comment and thus the comment would appear to annotate some other line of code. Refactoring tools help somewhat with this; but they only really do name matching in comments when you rename a variable.  Do you think renaming "i" to "count" really means replacing all "i"’s in all comments with "count"?  Probably not; don’t use refactoring tools as a crutch.

Helping the Reader Learn the Language


You can’t possibly know what the reader of your code does and does not know.  This is especially true of what they do and don’t know of language syntax.  The language syntax is your common language; you can only assume they know it. You can’t possibly know if a comment about language syntax is going to help the reader or not.  If they don’t know it, they should look it up.  Comments that describe syntax are a no-win proposition, you can’t possibly have a comment that helps every reader of the code.

An example:
        /// <summary>
        /// Constructor for class.
        /// </summary>
        public MyClass()

If your reader doesn’t know this is a constructor, they probably don’t even know what a c’tor is—this comment isn’t going to help them much. 

Slightly different example:

/// <summary>
/// Initializes a new instance of the MyClass class
/// </summary>
public MyClass()

If the reader doesn’t know what a c’tor does, does all your code include comments that will help this reader?  These comments are a waste of time and add no value. Same technical debt as Obvious, it’s not a syntax error to separate the comment from the declaration; there is a risk they will become disconnected or out of synch.  If the comment has no value having to manage it also has no value and therefore adds work to the project.

Another example verging on Obvious:
public MyClass()
{
  // Empty
}

As this stands, it seems benign. But one, it should be Obvious.  Two, if it’s not, the reader should be brushing up on language syntax.  Three, it’s not verified.  I can edit this c’tor to make it do something else this is perfectly syntactically correct:

public MyClass()
{
  x = 42;
  // Empty
}

Now, the comment is meaningless and potentially confusing.  Reading this for the first time makes you wonder did the class just have // Empty in it in the past and x = 42 was added, or does "empty" mean something different to the author, or did the author suffer from a stroke and possibly need medical attention?

You can assume the reader of your code doesn’t know anything about the code.  If the language can’t express the concepts in the code properly (if it can, you should be writing it that way; if you choose not to, comment why.) then comment why the language isn’t describing the concepts.

WHY not HOW


Writing comments to aid the reader in the understanding of the language is sometimes describing HOW the language is working.  That’s not describing the code but describing the language.  Comments should describe WHY the code was written that way if it’s not obvious.  Again, the language is the common denominator between the reader and the author.  There’s many references the reader can refer to to learn the language–let them do that; you may not be the best person to help someone learn the language; at the very least you don’t know the degree to which they don’t know the language.  Let the code clearly describe HOW.

Use of comments is often a form of religion; people are very opinionated about them in one way or another.   Robert Martin pulls no punches in Clean Code by saying:

“The proper use of comments is to compensate for our failure to express yourself in code. Note that I used the word failure. I meant it. Comments are always failures.”

Martin has previous described comments as “apologies” for “making the code unmaintainable”…

If you want to use concepts like XMLDOC or tools like JavaDoc to document members and classes, that’s fine; just make sure your comments are meaningful and can stand alone.

For what it’s worth, these are comments that I have encountered; more than once and on more than one project.

Do you have some code comment pet peeves?  We’d love to hear them!

(function() { var po = document.createElement(‘script’); po.type = ‘text/javascript’; po.async = true; po.src = ‘https://apis.google.com/js/plusone.js’; var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(po, s); })();

13 thoughts on “What Code Comments are Not For.”

  1. My fav comment of all time:

    //more efficient
    StringBuilder sb = new StringBuilder(“one” + “two” + “three”);

    (CAPTCHA is broken on Chrome)

  2. Excellent examples. I would add one more to your “list” of what code comments should be used for. I have been helped several times over the years when previous coders included comments explaining the business rules behind why something is being done a certain way — especialy when it’s counter-intuitive. But other than that, loved the list! Thanks!!

  3. I’d offer an alternate description:

    “Code tell you what your code DOES.

    Comments tell you what your code is SUPPOSED to do”.

    If code == specification, then no bug ever existed (by definition)

  4. I don’t agree with your // Empty comments.

    If someone just wrote “public MyClass { }”, and I had to take over the code, then I’d wonder what was going on.

    But if they put a // Empty comment in, I’d at least know that it was (presumably) deliberate.

    Better, of course, would be “// Empty because …”, but even just “// Empty” is helpful.

  5. @Larry. I imagine it is no surprise that I disagree.

    I fall back to Why not How. If MyClass{} isn’t obvious, then the comment explain why, not what. The fact that the MyClass constructor is empty is obvious; what isn’t obvious is why. Effectively re-stating the obvious provides you no value other than it was intentionality left blank–which leaves you equally in the dark as you were before.

    Most empty constructors should be obvious: private MyClass(){} is used to make sure the class can’t be instantiated by another if there are no other c’tors (e.g. Singleton), for example. private static MyClass() has the side-effect of making the compiler not to mark the type beforefieldinit. Both of these are language syntax, which the reader can read-up on if they’re unsure.

    Because you don’t know at what point the reader no longer needs language explanation; at what point to you stop adding comments to explain the language. If that’s huge issue on your team, I’d suggest walk-throughs, not code comments.

  6. It’s not necessarily a failure to express yourself in code, by explaining intent, any minor issues, or subtle mistakes can be realized to be just that, rather than require a full analysis to determine if that was actually intended, and if it was, why.

  7. I’ve sometimes found that code comments are valuable for documenting implicit code contracts. For instance, if one of the code parameters takes a map/dictionary/assoc.array/dyn.object, then there’s no explicit or enforced way for a consumer to know which data values must be set for the code to do its work.

    Of course, Bob would probably point out that the better course is to break up the code into smaller pieces and use real data types/classes as parameters instead. Explicit is better than implicit, but comments can help make the most of a bad situation.

  8. @James if the code doesn’t explain intent then a comment to explain WHY is good. But, always explaining intent regardless of whether it can be expressed in the code is the same thing as /helping the reader learn the language/ except that it’s the inverse, explaining to the reader what you know about the language. Also problematic because you don’t know what you don’t know and therefore must explain everything.

  9. @ArtV if you’re using .NET and a version that supports Code Contracts, it’s much better to express those pre/post conditions with code. It will be syntax checked and validated at compile/run-time.

  10. There are a couple additional uses for comments I like that I don’t see mentioned here:

    1) As Bookmarks to help you quickly identify code sections. In an IDE that supports code formatting, I find it useful to write lines like:

    // Load and process pledges first

    because I’ve set the IDE to show all comments in green, so comments stand out from the black text, and I can scan for comments and stop scrolling when I hit the right section.

    2) Identify TBD items. I’ll often drop in a comment like:

    // TBD Handle multiple allocations, probably using UNPIVOT command

    so that I can search for them later to finish up the pieces that still need work. The IDE I use for Oracle includes a ToDo feature that drops in formatted comments with Priority, Open and Closed Date, etc.

  11. I believe that quoting others in their hatred of comments is not helpful and doesn’t add value to the topic.

    “Comments are always failures.”

    This statement also seems to contradict your own views that comments should be used when “Describing why code isn’t doing something obvious”.

    The real disappointment in this article is quite simply because the vast majority of people who work in the real world are not working alongside MVP’s or for that matter, authors employed to devote extensive time writing on the subjective topic of “Best Practices”. What you’ll find is that developers have varying degrees of expertise and comments can assist in ensuring that developers, with less experience, understand the code that they have been tasked to modify.
    I can’t help but feel that your blog post simply assists in fanning the flames for the argument to drop comments all together. An augment evidently common to both code evangelists and lazy coder alike. XML headers are essential because they are displayed within the intellisense which is displayed to the developers when writing the code. This nugget of information seems to have been missed from you blog post. Admittedly, your examples adds little value to a developer who is trying to instantiate the object, however perhaps we should be encouraging developers to write more meaningful comments rather than none at all.

  12. @Tim I don’t necessarily think that they contradict. Code should be readable and obvious and not need to be explained–that’s why not many people use assembly any more.

    By detailing what comments are *not for* I was hoping to provide guidance to the experience levels you describe in your comment. Any guidance on how to write good comments is the opposite of dropping comments altogether.

    But, bad comments are worse than no comments. Comments are fragile and when done incorrectly have the opposite effect of reducing understanding of the code and reducing productivity.

    I’m sorry I didn’t write the post in a way that you could get any thing other than it “assists in fanning the flames for the argument to drop comments altogether”, I feel it does the opposite of that.

    If you provide more detail on what you think could be improved on this post, maybe I could do a follow-up. Many people feel Intellisense suffers from the same problem, it would be unnecessary if the API were intuitive. Even worse, you *must* known something about the API before you can even get to Intellisense.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>