Readability Beats Debugging

September 22, 2020 Colin Walls, Mentor

When writing code, your first priority should be readability. A lot of time is spent debugging and maintaining code, often far more than was spent writing it in the first place. So, making that process efficient is essential. Considering the needs of the human reader in the future (who might be you, of course!) is more important than trying to make the code “efficient” – that job can mainly be left to a modern compiler.

This consideration means that the code should be formatted and aligned very carefully, and language constructs should be as simple and transparent as possible. There are many published guidelines that help with these matters. However, creating readable code does not end there.

When you compile code, the programming language is translated into machine instructions. That is obvious. However, what the compiler actually receives is a stream of characters; some is actual code, but there may be chunks that are not intended to be translated and other text may be for human consumption only:

  • Documentation – comments in the code
  • Temporarily removed code – part of the debugging process, but it may persist
  • Special debugging/tracing code

Implementation of each of these has some influence on readability.

Documentation

Everyone knows that comments are a good idea, but most of us get lazy. However, some effort is very worthwhile. The old-style /*...*/ comment notation was acceptable, but the newer end-of-line //... form is clearer. Care is still needed. For example:

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

During software development, it is not uncommon to want to “hide” parts of the code from the compiler – to switch it off. The traditional way to do this was “commenting out” – putting a /* before the code and */ after. Although quick to do, it can easily be ineffective, as comment nesting is not necessarily supported by compilers. The newer // notation is a little better, but it is tedious to apply and remove and can still be error prone.

The best way to achieve this result is by using pre-processor directives, thus:

#if 0

   <code to be hidden>

#endif

Debug/Trace code

A particular kind of temporarily visible code is instrumentation – extra code added for debugging and/or tracing. Although modern debuggers and tracing tools can do a remarkable job, sometimes instrumenting the code is the only way to glean visibility and figure out exactly what is happening.

The usual way to accommodate this need is using pre-processor directives, as before, but using a symbol to switch them on and off:

#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

Although this double negative does seem confusing, some consistency is introduced, as this symbol is used to enable the standard assert() macro. The symbol needs to be defined to suppress debug mode.

Previous Article
Setup Violation Fixing in Timing Critical Complex Designs Using Late Clocking
Setup Violation Fixing in Timing Critical Complex Designs Using Late Clocking

Now a days the performance of these chips and clock frequencies are going higher and higher to meet the hig...

Next Article
Imagination and Packetcraft Announce Partnership for Low Energy Audio
Imagination and Packetcraft Announce Partnership for Low Energy Audio

Combining IMG iEB110 hardware with Packetcraft Bluetooth host stack to deliver a complete Bluetooth Low Ene...