On writing code with debugging in mind

/*************************************************
*                                                *
* .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. *
* |                   ______                   | *
* |                .-"      "-.                | *
* |               /            \               | *
* |   _          |              |          _   | *
* |  ( \         |,  .-.  .-.  ,|         / )  | *
* |   > "=._     | )(__/  \__)( |     _.=" <   | *
* |  (_/"=._"=._ |/     /\     \| _.="_.="\_)  | *
* |         "=._"(_     ^^     _)"_.="         | *
* |             "=\__|IIIIII|__/="             | *
* |            _.="| \IIIIII/ |"=._            | *
* |  _     _.="_.="\          /"=._"=._     _  | *
* | ( \_.="_.="     `--------`     "=._"=._/ ) | *
* |  > _.="                            "=._ <  | *
* | (_/                                    \_) | *
* |                                            | *
* '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' *
*                                                *
*    ABANDON ALL HOPE, ALL YE WHO ENTER HERE     *
*************************************************/
ASCII art image of a skull and crossbones with the text “abandon all hope, all ye who enter here” displayed below the skull and crossbones.

One factor of code quality that does not get enough attention is how easy is it to debug the code. No matter how skilled the team that writes the software, there will be bugs. When these bugs are found some poor soul will need to debug the code to determine the cause of the bug. Unfortunately this can quickly turn into a nightmare because many functions are not debuggable. Sometimes even well designed code is so difficult to debug that it causes the poor soul who has to debug it to abandon all hope.

Non-Debuggable Function

The following function is very simple. At first glance it seems to be a concise and well designed function. However, it is a major contributor to the debugging this application is a nightmare problem.


inline bool CCoolAppDocument::IsValidStartOffset(long nOffset) const
{
    return nOffset >=0 && nOffset < GetLength();
}

You may be wondering, how can this innocent, one-line function cause someone to abandon all hope?

When the function works as expected (meaning it returns the value you expect) it cannot. However, when the function returns false when you think it should return true the nightmare begins. The most critical piece of information that might explain why this function is not returning the expected value, the document length, is hidden away within a function call. As a result, there is no way you can look at parameter and variable values in the debugger watch window and know why the function is behaving in the way that it is.

Debuggable Function

The following function does exactly the same thing but it can be debugged in a microsecond.


inline bool CCoolAppDocument::IsValidStartOffset(long nOffset) const
{
    const auto documentLength = GetLength();
    return (nOffset >=0 && nOffset < documentLength);
}

All you have to do to debug this function is look at the value of the nOffset parameter and the documentLength variable in the watch window and then the reason for the unexpected behavior is immediately obvious.

In the case of today’s nightmare that inspired this article, the problem was that both the nOffset parameter and the documentLength variable happened to be equal to 296.

Additional Comments

I know that some of you are wondering whether I am aware that some debuggers will provide the return value of a function that was just called. The answer is of course I am aware of that. However, as far as I know not all debuggers support this functionality. In addition, this functionality is not as easy to use or as intuitive as the watch variable feature.

To me it just makes sense to make a very small change to make it possible to diagnose problems with the more intuitive and easier to use watch variable feature of the debugger.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.