27

I want to hear from you any advice and experience of writing comments in your code. How do you write them in the most easy and informative way? What habits do you have when commenting parts of code? Maybe some exotic recommendations?

I hope this question will collect the most interesting advices and recommendations forcommenting, something useful that everyone can learn from.

OK, I will start.

  1. Usually, I don't use /* */ comments even when I need to comment many lines.

    Advantages: code visually looks better than when you mix such syntax with one-line comments. Most of IDEs have an ability to comment selected text and they usually do it with one-line syntax.

    Disadvantages: Hard to edit such code without IDE.

  2. Place "dot" in the end of any finished comment.

    For example:

    //Recognize wallpaper style. Here I wanted to add additional details
    int style = int.Parse(styleValue);
    //Apply style to image.
    Apply(style);
    

    Advantages: Place "dot" only in comments that you finished. Sometimes you can write temporal information, so lack of "dot" will tell you that you wanted to return and add some additional text to this comment.

  3. Align text in the enumerations, commenting parameters etc.

    For example:

    public enum WallpaperStyle
    {
        Fill = 100,     //WallpaperStyle = "10"; TileWallpaper = "0".
        SizeToFit = 60, //WallpaperStyle = "6";  TileWallpaper = "0".
        Stretch = 20,   //WallpaperStyle = "2";  TileWallpaper = "0".
        Tile = 1,       //WallpaperStyle = "0";  TileWallpaper = "1".
        Center = 0      //WallpaperStyle = "0";  TileWallpaper = "0".
    };
    

    Advantages: Just looks better and visually more easy to find what you need.

    Disadvantages: Spending time to align and harder to edit.

  4. Write text in comment that you can't obtain by analyzing code.

    For example, stupid comment:

    //Apply style.
    Apply(style);
    

    Advantages: You will have clear and small code with only useful information in comments.

6
  • 2
    Align comments in vim: use Align.vim and do :3,7 Align // to align comments on lines 3-7.
    – Benoit
    May 23, 2011 at 19:38
  • 4
    "Hard to edit without IDE" - well, do you do that often?
    – user1249
    May 23, 2011 at 21:21
  • 4
    I think that a language/environment preference should be noted in the question. Some have existing guidelines (.NET has pretty standard xml comments: msdn.microsoft.com/en-us/library/b2s063f7.aspx). May 24, 2011 at 1:13
  • +1 SnOrfus. For Java-comments, to be used for Javadocs, the developer documentation, need to be placed in double-asterix comments, which have to be placed before your code. And Javadoc-comments are transformed to html, so you may use a bullet list, a table, an image or an url in your comment, and in all that cases, a trailing dot can be disturbing. May 24, 2011 at 11:19
  • 1
    I'm voting to close this question as off-topic because there is no question, just the poster's personal opinions on commenting style. Feb 11, 2020 at 22:08

11 Answers 11

17

Some of the statements below are quite personal, though with some justification, and are meant to be this way.

Comment Types

For the brief version... I use comments for:

  • trailing comments explaining fields in data structures (apart from those, I don't really use single line comments)
  • exceptional or purpose-oriented multi-line comments above blocks
  • public user and/or developer documentation generated from source

Read below for the details and (possibly obscure) reasons.

Trailing Comments

Depending on the language, either using single-line comments or multi-line comments. Why does it depend? It's just a standardization issue. When I write C code, I favor old-fashioned ANSI C89 code by default, so I prefer to always have /* comments */.

Therefore I would have this in C most of the time, and sometimes (depends on the style of the codebase) for languages with a C-like syntax:

typedef struct STRUCT_NAME {
    int fieldA;                /* aligned trailing comment */
    int fieldBWithLongerName;  /* aligned trailing comment */
} TYPE_NAME;

Emacs is nice and does that for me with M-;.

If the language supports single-line comments and is not C-based, I will be more enclined to use the single-line comments. Otherwise, I'm afraid I've now taken the habit. Which isn't necessarily bad, as it forces me to be concise.

Multi-Line Comments

I disagree with your precept using single-line comments for this is more visually appealing. I use this:

/*
 * this is a multi-line comment, which needs to be used
 * for explanations, and preferably be OUTSIDE the a
 * function's or class' and provide information to developers
 * that would not belong to a generated API documentation.
 */

Or this (but I don't that often any more, except on a personal codebase or mostly for copyright notices - this is historical for me and comes from my educational background. Unfortunately, most IDEs screw it up when using auto-format):

/*
** this is another multi-line comment, which needs to be used
** for explanations, and preferably be OUTSIDE the a
** function's or class' and provide information to developers
** that would not belong to a generated API documentation.
*/

If need really be, then I would comment inline using what I mentioned earlier for trailing comments, if it makes sense to use it in a trailing position. On a very special return case, for instance, or to document a switch's case statements (rare, I don't use switch often), or when I document branches in an if ... else control flow. If that's not one of these, usually a comment block outside of the scope outlining the steps of the function/method/block makes more sense to me.

I use these very exceptionally, except if coding in a language without support for documentation comments (see below); in which case they become more prevalent. But in the general case, it really is just for documenting things that are meant for other developers and are internal comments that really need to really stand out. For instance, to document a mandatory empty block like a "forced" catch block:

try {
    /* you'd have real code here, not this comment */
} catch (AwaitedException e) {
    /*
     * Nothing to do here. We default to a previously set value.
     */
}

Which is already ugly for me but I would tolerate in some circumstances.

Documentation Comments

Javadoc & al.

I'd usually use them on methods and classes to document versions introducing a feature (or changing it) especially if that's for a public API, and to provide some examples (with clear input and output cases, and special cases). Though in some cases a unit case might be better to document these, unit tests are not necessarily human readable (no matter what DSL-thingy you use).

They bug me a bit to document fields/properties, as I prefer trailing comments for this and not all documentation generation framework support trailing documentation comments. Doxygen does, for instance, but JavaDoc doesn't, which means you need a top comment for all your fields. I can survive that though, as Java lines are relatively long anyways most of the time, so a trailing comment would creep me out equally by extending the line beyond my tolerance threshold. If Javadoc would ever consider improving that, I'd be a lot happier though.

Commented-Out Code

I use single-line for one reason only, in C-like languages (except if compiling for strict C, where I really don't use them): to comment-out stuff while coding. Most IDEs will have toggle for single-line comments (aligned on indent, or on column 0), and that fits that use case for me. Using the toggle for multi-line comments (or selecting in middle of lines, for some IDEs) will make it harder to switch between comment/uncomment easily.

But as I'm against commented-out code in the SCM, that's usually very short lived because I'll delete commented-out chunks before committing. (Read my answer to this question on "edited-by in line comments and SCMs")

Comment Styles

I usually tend to write:

  • complete sentences with correct grammar (including punctuation) for documentation comments, as they are supposed to be read later on in an API doc or even as part of a generated manual.
  • well-formatted but more lax on punctuation/caps for multi-lines comment blocks
  • trailing blocks without punctuation (because of space and usually because the comment is a brief one, that reads more like a parenthesised statement)

A note on Literate Programming

You might want to get interested in Literate Programming, as introduced in this paper by Donald Knuth.

The literate programming paradigm, [...] represents a move away from writing programs in the manner and order imposed by the computer, and instead enables programmers to develop programs in the order demanded by the logic and flow of their thoughts.2 Literate programs are written as an uninterrupted exposition of logic in an ordinary human language, much like the text of an essay[...].

Literate programming tools are used to obtain two representations from a literate source file: one suitable for further compilation or execution by a computer, the "tangled" code, and another for viewing as formatted documentation, which is said to be "woven" from the literate source.

As a side note and example: The underscore.js JavaScript framework, notwithstanding non-compliance with my commenting style, is a pretty good example of a well-document codebase and a well-formed annotated source - though maybe not the best to use as an API reference).


These are personal conventions. Yes, I might be weird (and you might be too). It's OK, as long as you follow and comply to your team's code conventions when working with peers, or do not radically attack their preferences and cohabitate nicely. It's part of your style, and you should find the fine line between developing a coding style that defines you as a coder (or as a follower of a school of thought or organization with which you have a connection) and respecting a group's convention for consistency.

3
  • +1 for distinguishing commented-out code from documentation comments. I hate hunting those down :P
    – deltreme
    Aug 22, 2011 at 10:20
  • @deltreme: thanks. I feel your pain, I'm hunting a bunch of those myself in my current product as well. SCMs exist for a reason... I'm very tempted to just use a full-text search with a regex in Eclipse or Emacs and just eradicate them one by one... I have more productive things to do, sadly :(
    – haylem
    Aug 23, 2011 at 0:20
  • Please also see this answer on the use of action or task tags in comments.
    – haylem
    Nov 13, 2012 at 20:36
17

When I went to university I was always taught to comment every line of code and every method header. It was drummed in / indoctrinated to such an extent that you did it without question. Having been part of several Agile development teams at different companies I can say that I may write a comment once in a blue moon.

The reason for this is two fold, first of all we should no longer be writing long monolithic methods that do 101 different things, the class, method and variable names should be self documenting. Take the following login method as an example.

public void Login(string username, string password)
{
    // Get the user entity
    var user = userRepository.GetUser(username);


    // Check that the user exists
    if (user == null)
    {
        throw new UserNotFoundException();
    }

    // Check that the users password matched
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }

    //Check that the users account has not expired
    if (user.Expired)
    {
        throw new UserExpiredException();
    }

    //Mark user as logged in
    ...
}

This can be rewitten to something that is far more readable and perhaps reusable:

public void Login(string username, string password)
{
    var user = GetUserForUsername(username);

    CheckUsersPasswordMatched(user, password);

    CheckUserAccountNotExpired(user);

    MarkUserAsLoggedIn(user);
}

private void User GetUserForUsername(string username)
{
    var user = userRepository.GetUser(username);

    if (user == null)
    {
        throw new UserNotFoundException();
    }
    return user;
}

private void CheckUsersPasswordMatched(User user, string password)
{
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }
}

private void CheckUserAccountNotExpired(User user)
{
    if (user.Expired)
    {
        throw new UserExpiredException();
    }
}

You can clearly see from the login method what is going on. You may see this as extra work but your methods are small and only have one job. Additionally the method names are descriptive so there is no need to write any method header comments. If you end up with too many methods this is an indication that the related methods should be re-factored into another object such as a UserAuthenticationService, remember an object should only have one job.

Secondly every single piece of code that you write, including comments, has to be maintained, the more comments you have the more there is to maintain. If you rename a class or a variable you will get a compilation error but if you change the way a section of code works or remove it and do not update any related comments then there will be no compilation error and the comments will hang around causing confusion.

If you are writing an API then I do believe that any public facing interfaces, classes, enumerations should have well written header comments for documentation.

2
  • 2
    I totally agree with this. Well named short methods are self documenting. More often than not, I write very few (if any) comments in code, and I'll write one fairly large wiki page with code examples (mostly done when you're writing a library that other developers will use).
    – Kevin
    May 25, 2011 at 15:31
  • 2
    This is exactly what I came here to say. In fact, I spend just as much time thinking of variable names, method names, class names, etc., as I do writing code. The outcome, I believe, is very supportable code. Sure, I sometimes have methods that are named something like checkIfUnitInvestigationExistsAndCreateNewRootCauseListIfItDoes()... yes, method names SOMETIMES get long, but I think the suportability of the code is the most important facet of development (aside from the speed of release). May 25, 2011 at 15:40
5

Focus less on the format and more on the content. For instance the comments in you example tell me nothing new. They are worse than worthless as they detract from reading code, and comments such as these are at best a vague reference to what the original programmer thought he was doing at the time he wrote it. I can see from the code example that you are applying a style apply(Style), I can read source. I cannot read your mind, - why are you doing it is what the comment should tell me.
e.g. rather than

//Apply style.
Apply(style);

should be

// Unlike the others, this image needs to be drawn in the user-requested style 
apply(style);

Most of us work in teams on existing code, format the way the rest of the team does,the way it's already being done. Consistency of far more important than pretty.

2
  • Read more carefully what that example for. I have already mentioned that: "For example, stupid comment:".
    – kyrylomyr
    May 24, 2011 at 0:38
  • 1
    I take your point. I am sure you won't be surprised how many "stupid comments" I have seen in real code, so I stand by my post. the format does not matter, the content does.
    – mattnz
    May 24, 2011 at 1:08
4

As much as possible, write your code such that comments would be completely extraneous. Only add comments when the code can't be written in such a way that it would make an important concept obvious.

2

My own preference is to keep it really simple. I eschew all kind of fancy formatting. The main reason for this is that I think source code should be comfortably editable with even the simplest text editor. I also never hard wrap paragraphs of text but instead let the editor do soft wrapping (no adding of newlines).

1
  • I've never seen soft-wrapping in comments. I don't think it's such a good idea, but I guess that's fine as long as you keep it consistent. May 23, 2011 at 21:21
2
  1. Pick a documentation system such as doxygen and stick with it. Keep checking on the documents produced.
  2. Try to picture someone new to the code base coming in and reading your docs, could they get a running start with it? Interns are actually good for that, sit a new one down with your existing doc base and a simple task and see how far they get, if they stumble, much sure anything you told them to get them going again goes in the docs.
  3. Make documentation comments a checkpoint in your review processes.
2

Here's an "anti-pattern" I've found throughout my job's code: The use of comments as a "change log"; that's what the log in your version control system is for. The code is littered with things like:

// 05-24-2011 (John Doe): Changed this method to use Foo class instead of Bar

and usually often includes the old code that's been commented out (again, that's the point of a VCS system so doesn't need to be in the code after new code is written). Also something to avoid is repeated comments like "Why do we need this?" or worse still, "This should probably be renamed" (because there are sophisticated tools for renaming, so in the time it took you to write that comment you could have renamed the thing). Again, I deal with both of those comments on a regular basis, along the lines of:

// (John Doe) 05-24-2011 not sure why we are using this object?
FooBar oFooBar = Quux.GetFooBar(iFooBarID, bSomeBool);
oFooBar.DiscombobulateBaz();

// (John Doe). This method is poorly named, it's used for more
// than just frazzling arvadents
public int FrazzleArvadent(int iArvadentID)
2

I often see comments like that, and some tools automatically generate it that way:

/**
 * This is an example, how to waste vertical space,
 * and how to use useless asterixes.
 */

Two lines less:

/** This is an example, how to spare vertical space,
    and how to avoid useless asterixes. */

IDEs and Editors, marginally above the notepad-level, are able to detect comments and to print them in a different color. There is no need to decorate the beginning of the line with asterixes.

You even spare some bytes, if you use a tab for indentation.

If you don't use an sophisticated editor, which renders the comment in a grey tone, the great amount of asterixes will work as an emphasize and attract your attention, which is the opposite of the right thing to do: to stay behind.

5
  • In that case, IDEs and Editors can use code-folding, if your concern is to save screen real-estate. If your concern is to save bytes, you need to stop coding on you Commodore 64 :) More seriously, if you want to save bytes (for client-side code for instance), then a compiler or minifier will do this for you as you won't need the comments in production. Code size matters as the more code you have, the bigger the chance of bugs (arguably). But the total file-size shouldn't really be a concern in a modern process. Code away store in an SCM, and maintain accordingly.
    – haylem
    May 25, 2011 at 1:01
  • If working w/ a crappy editor, asterixes don't attract my attention as they are comments and their alignment makes it clear. If I were reading code for a dynamic scripting language, then using your style with a crappy editor with no highlighting whatsoever would be harder on my eyes as it would take me a slightly longer time to process whether or not what I'm saying is a whole comment block or some weirdly wrapped code statement. This is probably person and the result of one's habit though, but that's how I'd perceive it.
    – haylem
    May 25, 2011 at 1:04
  • I don't like to spend my time folding and unfolding code. I would agree to your commodore-argument, if the bytes would have a single advantage, but they don't. If your editor doesn't have code-highlightening, go, buy yourself a Commodore64. :) The indentation argument doesn't hold, because if the indentation separates the comment from the code, it separates the code from the comment too. Look at a bigger piece of commented code - a block of asterixes works as an emphasis. May 25, 2011 at 3:45
  • Like I said, might be personal. But think about it: do you really see all those shiny and funky ads while your browse the web? Most people don't. You just learn to block them out, as you've just registered them as a general pattern you can easily mind-block. Works for me for doc comments. About the folding, it can be tedious. For Java, my Eclipse is set to fold a lot of things by default, because I like to open my Java files and be able to survey them like C header files (w/o using the outline view). And I use Mylyn to only display bits I work on.
    – haylem
    May 25, 2011 at 8:24
  • Yeah, I learned to block them out - with a plugin, called ad blocker. Eclipse has a fold function, but gedit, which I use for small, single file programs, hasn't. May 25, 2011 at 8:51
2

The most important recommendation is:
Comment the unexpected, not the obvious!

A comment like this is useless:

// Adds a to b and write the result to c
c = a + b;

It just repeats what the code says and you shouldn't write comments for people who don't understand code as if they don't understand code, they won't read any code and if they don't read any code, they won't read your comments either. Keep in mind that you write comments mainly for other people that are able to understand code about as good as you can understand it.

Thus most of the code shouldn't require comments at all because if most of your code is so clumsy that it cannot be understood without comments, something is wrong with the code or your coding style. Comments should be the exception, not the rule, and this means that the style of your comments is nowhere near as important as your code style.

When placing comments in your code to comment the non obivous, I would recommend to keep them simple, short, and straight to the point. Such kind of commends don't even have to be grammatically correct sentences or use punctuation. They are like additional code, just not for the compiler but for human beings.

// Setting owners must happen on main thread
// and this function must not block
if (!info->owner) return errMissingOwner;

How is that a good comment? A programmer just reading the code may wonder "If there is no owner, why not just setting one instead of returning an error?" The comment gives the answer: Because it must happen on main thread and this statement alone implies the function is probably not running on main thread. Okay but then a programmer may wonder "Why not just dispatching to main thread?" and the comment gives the answer: The function must not block and you cannot guarantee that it won't block unless you know for sure what the main thread is currently doing. So the comment answers all the questions the code alone cannot answer and none of these answers are obvious. Thanks to the comment the reader will know why failing with an error is the only meaningful option here and it also helps future programmers that want to touch the code to not make a stupid mistake.

Yet the real important comments are comments for the purpose of documentation. If somebody only knows your interface but not the implementation, then comments are the only additional source of information on how to use your code correctly and what behavior to expect. These comments should be well readable, usually whole sentences, and use correct grammar and punctuation.

/// Sorts an integer array in place. 
/// The sorting algorithm is stable.
/// Sorting takes O(n * log2(n)) time 
/// and at most (n / 4) * sizeof(int) memory.
///
/// @param array The array to be sorted.
/// @param count Number of elements in the array.
///
/// @return @c false if memory allocation failed and
/// the array wasn't touched, @c true otherwise.
///
bool sortIntArray ( int * array, size_t count );

Without that comment, a programmer may guess what the function does and what the parameters mean but it's impossible to know if the sorting is stable, what bounds on time or memory it will have, or for what reason the operation might fail and what the exact consequence of failing will be.

1

Code readers usually are trying to answer three questions:

  1. What does this class or function do? If this is hard to answer, then it does too much. Code that is hard to document is usually just wrong.
  2. How do I use it? An example may be good enough.
  3. That code is surprising. Why did you do that? Most likely answers: to work around a bug in third-party components, because the obvious technique proved to be too slow

Everything else should be expressed in the code. Like writing prose, this is an art, and takes a lot of practice. The only way to know if your code is understandable is to get someone else to read it. When they don't understand something, don't explain it verbally. Improve the code. Add comments as a last resort.

If I see "double length" I will ask "What is the unit of measurement?" Don't add a comment. Change the variable name. If I see a block of code and I say "what does this do?", don't add a comment. Extract a function with a meaningful name. If you can't extract a function because it would need 17 arguments, then refactor the code.

1

Somewhat an odd answer but, the best kind of comments are *no comments*.

If your code is clear, clean and honest:

You do NOT need comments.

Comments lie and are hard to maintain. (one of the many links on Google talking about it)

Try to name your method to hint the intention, adhere to the single responsibility principle whenever possible and your code will read through like a breeze without needing any pesky comments.

(See bronumski's answer for some code examples)

5
  • 1
    Method names lie, too. Variable names lie. Class names lie. Code lies. Feb 11, 2020 at 12:14
  • @ChristianHackl A lot less and refactoring tools will change it all very easily but will leave your outdated comments intact. While true, it applies a lot less especially if you try to do clean, honest code as I mentioned.
    – jeromej
    Feb 11, 2020 at 12:46
  • 1
    If you can change a wrong name in code that otherwise works perfectly, then you can (and should) also change an outdated comment in it. The hard thing are lies in code that don't have anything to do with names, for example classes which are not meant to be instantiated, interfaces for which only one particular implementation makes sense or local constants which are declared as mutable. "Code doesn't lie" is just a popular myth. Feb 11, 2020 at 12:58
  • @ChristianHackl I'm not sold. When I rename my methods or change their signature, I don't check every usages to check if there are comments around nor do I need to if I don't have said comments because my method are honest . Anyhow, we shouldn't chat in the comments. (But we can move it to chat if you want)
    – jeromej
    Feb 11, 2020 at 13:05
  • Another example of better coding is changing your method to only accept only parsed data (have a specific type which can only hold valid values or throw an exception). This way you do not need to comment what kind of data you receive and parse it after you received it. You know it only accept valid inputs and won't even compile otherwise.
    – jeromej
    Apr 27, 2021 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.