Why is so much Embedded Code Unreadable?
The idea of readable code – that it should be written to make it as easy as possible for future readers to understand – is not new. Brian Kernighan and PJ Plauger’s book, The Elements of Programming Style, was first published in 1974, around the same time as the embedded software industry was taking off. Since then there have been many well-known books that cover similar ground (listed below).
The importance of readability is not just about aesthetics and beautiful code – although that plays a part – but it relates directly to the overall lifecycle cost of software. Code that is hard to read is more likely to have undiscovered bugs, and is inevitably harder to maintain than readable code. This is surely as much of an important factor for embedded software as it is in other fields.
You’d think, then, that developers building embedded systems 40 years later would be applying these principles as a matter of course. But at Pebble Bay, where we often work with source code from other companies, we find this is rarely the case: embedded software source code is often very hard to read – sometimes shockingly so. There are exceptions, of course, but in most cases, code that we inherit from other companies falls a long way short of the standards for readability that we set ourselves.
This raises some obvious questions. First, is this unique to embedded software? That’s hard to answer without knowing about non-embedded software development, but for us it’s a moot point anyway. Secondly, why is there apparently so little regard for readability of embedded software?
Advice and guidance on readable code
It can’t be for lack of guidance. Apart from the excellent (though now dated) Kernighan and Plauger book, there’s a wealth of advice on how to write readable code. Some of our favourites at Pebble Bay are:
- Code Complete, by Steve McConnell (Microsoft Press)
- The Practice of Programming, by Brian Kernighan and Rob Pike (Addison-Wesley)
- The Pragmatic Programmer, by Andrew Hunt and David Thomas (Addison-Wesley)
- The Art of Readable Code, by Dustin Boswell and Trevor Foucher (O’Reilly)
These books present many principles and practical techniques to improve the readability of code. The techniques apply from the micro level – within single lines of code – to the macro level – organisation of projects. Furthermore, there’s a lot of consistency and agreement between different writers. So the truth is out there, at least in traditional published book form.
While a web search for “readable code” returns many interesting blog posts and articles, “readable embedded code” brings up more or less nothing directly related to the topic. I find that interesting, but also rather disturbing. Of course, you can apply the same general principles to embedded software development, but does this mean no-one developing embedded software takes readability seriously enough to talk about it?
Perhaps it’s not quite that bad. One of my favourite embedded software blogs is Nigel Jones’ Stack Overflow (http://embeddedgurus.com/stack-overflow) where readability and maintainability are recurring themes. For example, his June 2012 post The Crap Code Conundrum explores similar ground to this article.
Possible reasons for poor readability of code
I can think of several reasons why embedded software might be unreadable:
- Not enough experience or knowledge of how to make code readable
- Lack of pride and/or perceived value in producing readable code
- Not enough incentive or motivation to make the code readable
- Time pressure precluding (perceived) effort needed to make the code readable
- Code prematurely ‘optimised’ at source code level resulting in poor readability
- No process to ensure or improve readability
There are a couple of threads here. One is a personal quest for self-improvement and a pride in writing high-quality, readable code. That depends on developing the maturity to avoid overly-dense, complicated or ‘clever’ code either for its own sake or in a misguided attempt to improve some vague notion of ‘efficiency’. Different people may have that self-awareness, self-discipline and drive for improvement to different degrees. Interestingly, Nigel Jones suggests that low awareness of the need for readability and maintainbility is probably the most likely cause for the poor quality of a lot of embedded code.
But the second thread is that an organisation that depends on embedded code must make readability a stated, explicit goal – and maybe even enforce quantitative measures of readability where possible. This implies the need for a process, to reduce the dependency on individual attitudes and capabilities. Without this, organisations can’t consistently develop readable, maintainable code and will therefore spend more time and money than they need to over the complete life of their software.
I would argue that this focus on readability is an essential part of a software engineering process, and in fact, should not add much extra effort within that context. Just to pick a simple example: you’re almost certainly going to review the code to detect defects, so the same review is an ideal opportunity to ensure and improve readability.
What is needed to improve readability of code?
At Pebble Bay we’ve determined that three things are needed to consistently develop readable code:
- a commitment that code readability is required and will not be compromised;
- a set of standards, principles and guidelines to explain what ‘readable code’ means and how to achieve it; and
- a consistently-applied review process to ensure that code meets or exceeds the agreed standards.
After all, this is hardly a radical conclusion – you could replace ‘readability’ with ‘low rate of defects’ and exactly the same approach would apply. So is there something missing? What other reasons are there for the low standard of readability in embedded code, and what techniques do you use to improve it? What characteristics best define readable code for you?
Hi Ian; besides the oft-cited “delivery schedule” problem (which of course actually means an *unrealistic* delivery schedule), I suspect that very often the programmer is flying solo; there *aren’t* any teammates for code reviews. This has certainly happened to me, and I must admit that I have written some very sloppy atrocious code when only I will ever see it; I’m much more careful, when I know that other people — people who’s opinions I value and respect — will be looking at it.
This is a bad habit that I continue striving to eliminate, and now try to ensure that *all* my code is exemplary, with nothing to apologize for… Which leads to another problem that I’ve encountered: derailment.
The code has *functionally* passed through the shakedown iterations, and has graduated to commitment in the production release. I’m now going to tidy it up and make it nicely readable (if not utterly beautiful), really, I am. But then comes an “urgent priority” to work on a different module, then another, and another…
The road to hell is paved with good intentions. :-/
cheers, – vic
Hello Vic – thanks for your comment. I recognise those effects too; personally, the way I’ve learned to avoid them is to get in the habit of writing the code “nicely” at all stages of a project. If you like to think of it that way, I am my own code reviewer. Even when prototyping, the time spent in apparently cosmetic detail is usually repaid later in the project. That way there is no large, looming clean-up task that — as you say — tends to never get done. Sure, when my colleagues review the code they pick up defects that need to be fixed, but at least there is (usually) a manageable number of them.