Unrecognized Escape Sequence

An increasingly grumpy blog about software engineering

Bad comments

Have you ever noticed that comments usually appear greyed out or pale in most IDE colour schemes? This includes the markdown for this very post. I suspect that this is because in our collective consciousness as coders, we don’t think very much of comments. Comments are equivalent to a footnote in a book – an optional extra that doesn’t really need to be read. I mean, almost the first thing a compiler does is remove all the comments. They’re that disposable, right?

It’s a shame that this – at best unconscious – belief exists, as comments can play a really important part of helping to make code more readable and understandable. The likely reason for this belief, at least from my experience anyway, is that comments are misused a lot.

The smell of bad comments

There are lots of bad smells around comments, which superficially can seem like a harmless addition to your codebase. Some common examples include:

  • Comments that are just stating the obvious, and cluttering the code
  • Comments that have become out of date, after the code around them has been changed or refactored
  • Comments that were written by a coder five abstractions deep, and completely unintelligable by someone else coming to the code later

The good news is that most of these smells can typically be addressed quite easily.

Some example solutions

To take the first of these smells as an example, I’ve described here a couple of the approaches I’ve taken in the past to try and fix them when I come across obvious, cluttering comments.

Here’s a classic case of “telling a story”, self-evident comments that are semi-useful as you read the code for the first time, but shouldn’t need to exist. Comments like these might as well be greyed-out by the IDE, as they do and say so little:

int main()
{
    // Create objects

    MainWindow* mainWindow = new MainWindow();
    NetworkRequestFactory* networkRequestFactory = new NetworkRequestFactory();
    DownloadManager* downloadManager = new DownloadManager(networkRequestFactory);

    // Connect the signals

    connect(downloadManager, &DownloadManager::progress, mainWindow, &MainWindow::onProgress);
    connect(downloadManager, &DownloadManager::downloadComplete, mainWindow, &MainWindow::onDownloadComplete);

    // Show the window:

    mainWindow->show();

    // Start download

    downloadManager->startDownloading();

    // Start event loop

    mainWindow->exec();
}

Solution A: Making the comments come alive

Maybe these kind of comments are a smell that the code needs to be broken down into smaller functions. In other words, if the comments are telling a story, maybe this story needs to be in chapters :eyes_rolling:.

Self-documenting function names are ‘alive’ in the sense that they are understood by refactoring tools and will be renamed accordingly if and when the code evolves. So instead of using comments, simply extract methods and let the method names capture the narrative:

int main()
{
    createObjects();
    connectSignals();

    mainWindow->show();

    downloadManager->startDownloading();

    mainWindow->exec();
}

Solution B: Making comments do something

Maybe if comments actually did something, they would be more respected, like when comments are marked up for use by documentation tools. Another alternative is turning comments into logging or code tracing. This way, the comments have the additional benefit of documenting the code at runtime:

int main()
{
    debug() << "Creating objects...";

    MainWindow* mainWindow = new MainWindow();
    NetworkRequestFactory* networkRequestFactory = new NetworkRequestFactory();
    DownloadManager* downloadManager = new DownloadManager(networkRequestFactory);

    debug() << "Connecting signals...";

    connect(downloadManager, &DownloadManager::progress, mainWindow, &MainWindow::onProgress);
    connect(downloadManager, &DownloadManager::downloadComplete, mainWindow, &MainWindow::onDownloadComplete);

    debug() << "Showing window...";

    mainWindow->show();

    debug() << "Starting download...";

    downloadManager->startDownloading();

    debug() << "Starting event loop...";

    mainWindow->exec();

    debug() << "Done. Exiting...";
}

Final thought

Of course, a good comment can be absolutely essential and invaluable – a way for one programmer to make things easier for another. Ideally, a well maintained codebase should aspire to reserve the use of comments for these situations, and remove all others.

If you ever reach such a place, remember to change your IDE settings so that comments are no longer greyed out.