A couple of weeks ago, I posted a summary of Jack Ganssle’s first two articles (from a series currently running on embedded.com) discussing reasons Ten and Nine why embedded development projects “run into trouble.” Here are reasons Eight and Seven:
8 – The undisciplined use of C and C++
As embedded systems developers we quite naturally rely on C and C++ (along with C#, Assembler, Java, Ada, and a variety of scripting languages including Linux shell scripts, Perl scripts, Windows batch files, by the way…). So I was quite naturally intrigued by what Jack has to say about their use.
First off, he reminds us that language-wise, C is right up there with Latin, dating back to 1972. (Which, he points out, makes it older “than most embedded developers”. Just not me.) He notes why C and C++ are so attractive:
C is uniquely suited to deeply-embedded work as it excels at manipulating bits, bytes and hardware. It’s a great choice for real-time work as it doesn’t have some of the problematic features of more modern languages, like garbage collection. C++, of course, brings the advantages of object-oriented programming to the discipline.
But then goes on to talk about why he believes that using them can be dangerous, especially for those lacking in expertise.
C/C++ have unspecified, implementation-defined, and undefined behaviors. Lots of them…There are plenty of ways to get stung even outside of these behaviors. Consider dynamic memory allocation. That’s a very useful feature for RAM-constrained systems. But it’s fundamentally non-deterministic. Malloc and free, malloc and free, and there’s no way to prove that some strange combination of inputs won’t cause enough heap fragmentation that the requested allocation fails.
When there’s no choice but to use dynamic memory, a disciplined use of C is to check malloc’s return value and take some action if malloc was unable to do its job. Yet I almost never see that test performed.
Jack then dives into the perils of pointers. Definitely worth reading him for the warnings he lays out. He ends his article by underscoring that he is, in fact, a proponent of C/C++. Just that he’s against their undisciplined use. Anyway, I’d like to point out that we, too, are proponents of C/C++ and very much committed to their disciplined use.
This article is a very cautionary discussion on the importance of understanding the science underlying the products we’re developing embedded systems for. Take nothing for granted, he warns. Don’t assume you get the science. Delve into it and make sure that you’ve got things straight.
His illustrations are interesting. For starters, he discusses a system built in the wayback that used IR light to measure grain proteins.
Spinning filters created 800 distinct wavelengths which impinged on the sample. Lead sulfide detectors read the reflected signal which was digitized and handled by an 8008.
Did you know lead sulfide detectors are more sensitive to temperature variations than to light? We didn’t. The data was garbage, and for months we sought answers before learning this simple fact. More months were lost as we tried cooling them with Peltier plates… and they got too cold. The final solution was a combination of carefully-controlled Peltiers and heating elements.
He provides another example that involves using carbon tetrachloride. Bad decision:
We didn’t know that carbon tet is quite toxic when inhaled; OSHA nailed us.
The substitute they used just plain didn’t work.
The solution to these and other bad science problems: do your research. For Critical Link, that means working in close partnership with our clients to make sure we understand the underlying science behind their applications, and the implication this has for the embedded solutions we develop for them. (I’m going to do a bit of a brag here: we’re really good at this.)
Jack’s series is really a must-read for engineers in the embedded space, and I’ll be posting summaries of the other reasons over the next couple of months.