“I’d spell ‘creat’ with an e.” – Ken Thompson, when asked what he’d change about Unix.
Look up “panacea” and you’ll find a bunch of C programming tools. Everyone and his dog has ideas about how to create better, more reliable C code. Use an ISO-certified compiler. Follow MISRA C guidelines. Write the comments first. Agile Programming. Energy crystals. The late-night remedies never end.
Or, you could learn from the master. Michael Barr does embedded programming. He’s got a Masters in electrical engineering; was an adjunct professor of EE/CS; was Editor-in-Chief of Embedded Systems Programming magazine; founded consulting company Netrino to teach people how to write better code; then founded Barr Group to do it again. The man knows a few things about writing embedded software, mostly by watching his clients and students doing it badly. There’s no substitute for experience, and this guy has collected decades worth of it.
So it’s no surprise that he’s come up with his own little black book of programming pointers. These are the rules, guidelines, and suggestions gleaned from years of reviewing other peoples’ bad code and then fixing it. Best of all, a PDF download of the book is free. If you’re a traditionalist, you can buy the paperback version from Amazon.
Unlike some of the more radical approaches, Barr isn’t trying to redefine the C language itself. That’s a fool’s errand, and no programming language can ever truly prevent bad code. Programming languages are like power tools: they need to be treated with respect and used for their intended purpose. C is open-ended enough (some have called it “sugar-coated assembly language”) that it leaves a lot of room for misuse.
Instead of changing the language, Barr tells us how to change our habits. He uses totally standard C, but in a safer and more reliable way. Certain aspects of the language are dangerous, he says, while other parts are just fine. Stay away from the scary bits and you’ll be okay.
His work piggybacks on that of MISRA C, the 20-year-old guidelines first created for the British automotive industry to promote more reliable programming. MISRA has been the gold standard for a lot of embedded programmers, and it’s still applicable. But MISRA deliberately avoids the contentious issue of programming “style,” the often-personal quirks of indentation, commenting, naming conventions, capitalization, and so forth. These are generally things that the compiler ignores, but that can make source code much more (or less) readable.
Barr has no such qualms. He’s quite happy to enforce a style guide – in fact, he insists on it. That’s grown out of his years of consulting with programming clients and slowly building an in-house style guide. “Every new style rule had to pass a judging contest,” he says. “We adopted new rules based on convincing arguments for how it reduces bugs, not who talks the loudest.”
As an example, Rule 1.3 says that all functions, however trivial, must surround the operational statements in curly braces. That includes single statements and empty (null) statements; no exceptions. Furthermore, the braces must be on a line by themselves.
Plenty of programmers will say this is a waste of space (what space?) or that it makes simple procedures seem overly complicated. They prefer quick one-liners.
In his defense, Barr says that, “Code constructs [without braces] are often associated with bugs when nearby code is changed or commented out. This risk is entirely eliminated by the consistent use of braces.” Regarding the highly subjective issue of style, he says, “The placement of the left brace on the following line allows for easy visual checking for the corresponding right brace.” It’s hard to argue with that.
Be generous with parentheses. Don’t rely on C’s operator precedence rules to make arithmetic operations come out correctly, even though they will. Precedence might be obvious to you, but not to your successor, so why risk it?
Don’t use the keywords auto or register. Just don’t.
In addition to line-by-line rules, the Barr’s 74-page guide includes some overarching guidelines that should be tacked on every cubicle wall.
It’s Not Your Code
You don’t own the software you write. Your employer does. Any code you create is “work for hire,” and you’re not entitled to do whatever you want with it. That sounds a bit harsh, but it’s legally true, in the same way that novelists don’t retain the copyright to their own books (their publisher does), or the way movie studios own a director’s original works.
A more subtle point here is that you don’t really have the freedom to hack out code any way you like. You owe your employer a “duty of care:” a responsibility to be professional and workmanlike. You wouldn’t hire a plumber or an electrician to just “wing it” and cobble together something for an hourly fee. You expect tradesmen to be certified, professional, and up-to-date on all the latest building codes, safety requirements, and best industry practices, whatever those may be. Likewise, programmers who charge for their work and expect to be treated as professionals really ought to follow the best-known industry guidelines and practices, especially when those rules have been shown to reduce bugs and increase maintainability. “But I’m an artiste” is not a valid excuse for any programmer.
C Is Sloppy
The C language definition is insufficient to create reliable code. You can follow the C specification religiously and still create bad, buggy code.
“So what?” you say. The language can’t protect us from ourselves, any more than the rules of English grammar can prevent nonsense sentences (James Joyce notwithstanding). But the problem is more elusive than that. Even rock-solid, by-the-book, ISO-certified compilers have leeway – too much leeway, in Barr’s view – to interpret various “implementation-specific,” “undefined” or “unspecified” loopholes in the ISO standard. Thus, different compilers can, and do, produce substantially different runtimes from the same source code, even though everything is squeaky clean and adheres to ISO standards. You simply can’t rely on the current specifications to keep you out of trouble.
You’re Writing for Posterity
Barr states that, “…reliability, readability, efficiency, and sometimes portability of source code is more important than programmer convenience.” In short, don’t take shortcuts. A clever, but dense, assignment may make you feel inventive, but if it’s hard to read, hard to understand, or hard to modify, it’s not a good choice. We don’t write code for our convenience. We write for the compiler (and other tools) and for the poor slob who maintains the code after we’re gone.
He goes on to say, “As the original author [of the software], you can create bugs two ways: by yourself, or by making it so hard to understand that someone else breaks it (which may be a future you).” Again, clarity is key. Comments won’t bloat the object file, and nobody’s going to scold you for taking up too much disk space on the development system. Be generous with your comments and feel free to expand functions to make them clearer. The sanity you save may be your own.
In automotive engineering, the most important piece of hardware is the nut behind the wheel. In IT circles, it’s PEBKAC . Among programmers, there are tools to catch errors, but none is as important as the programmer who put them in there. A spellchecker can’t fix sloppy writing, and a compiler can’t fix bad code. We need to treat programming more like engineering and less like creative writing, with all the discipline that implies. Only then can we call ourselves professional software engineers.