Comments and debug code
I have frequently asserted that one of the most important attributes – maybe the most important attribute – of code is readability. This is because an enormous amount of time is spent on debugging and maintaining code – far more than that expended on writing it in the first place. So, keeping the future human reader [who might be you!] in mind at all times is essential.
Interesting challenges occur when you think about hiding text/code from the compiler …
Consider the general concept of concealing things from the compiler. It receives a stream of characters, which need to be translated into machine instructions, except where they are intended solely for human consumption. There are three broad contexts in which stuff is hidden from the compiler:
- documentation – comments in the code
- temporary code removal – an inevitable part of the debugging process
- debug/trace code – which can be switched on and off, as required
Taking these in turn …
Documentation
Everyone knows that comments are a good idea, but we are all lazy. However, the effort is well worthwhile. Old style /* … */ C comments are OK, but I feel the C++ end-of-line [ // … ] variety tend be be clear. They still need to be used with care. For example, code like this:
int number; // input count char c; // single character buffer char buffer[99]; // the input line
is so hard to follow. Alignment is everything:
int number; // input count char c; // single character buffer char buffer[99]; // the input line
And do not use tabs. They are not portable.
Temporary Code Removal
In the process of debugging and testing code, it is commonly useful to be able to “switch off” a chunk of code temporarily. Many programmers “comment out” code to achieve this result by putting /* at the beginning and */ at the end. That is quick and dirty, but frequently fails to achieve the required result. Many compilers do not support nested comments, so, if the code was commented, problems arise. Overall, it is error prone and should be avoided.
The use of C++ style // comment notation – i.e. putting // at the beginning of each line is marginally better, but very tedious to apply and may also be error prone in removal.
The best way to achieve this result is by use of pre-processor directives, thus:
#if 0 <code to be hidden> #endif
In any case, “turned off” code should not be included in any code which is being considered for release.
Debug/Trace Code
Another kind of temporary code is that included to facilitate the output of extra information when debugging. Although modern debuggers and such tools can be very effective, instrumenting the code can still be the best way to figure out exactly what is going on. Modern development tools are so fast that rebuilding to create a debug-enabled image is not a serious overhead.
A common way to facilitate this is using pre-processor directives, thus:
#ifdef DEBUG_TRACE <debug/trace code> #endif
So, when the symbol DEBUG_TRACE is defined, the debug code is included.
A slightly different approach is to code it like this:
#ifndef NDEBUG <debug/trace code> #endif
This double negative seems clumsy, but this symbol is used to control the standard assert() macro. The programmer needs to define the symbol to suppress debugging mode. I acknowledge Michael Barr, who raised my awareness of this approach in “Embedded C Coding Standard”.
Comments
Leave a Reply
You must be logged in to post a comment.
The typical advice you get regarding comments: give your variables descriptive names instead of using comments to explain them. This makes the code where they are used also clearer, as opposed to just the code where they are declared.
I don’t have an issue visually decoding nonaligned comments, but I understand some people do.
One of our coding standards says #if 0 is verboten to use (why do we have more than one coding standard you may ask…. )
The last example is interesting.
Finally, I tried looking on the internet for this joke about comments, had no luck so this is as close as I can remember
If I wanted you to understand it, I would not have written it in code
@Tudor – I agree. The first step to documenting code is sensible naming of objects.
@Keith – Your “joke” makes a serious point [as the best ones always do]: writing code to be clear for the future human reader is a high priority.