Careful C craftsmanship creates correct code.
I'm just back from three weeks overseas. Despite daily trying to keep up with email, some just has to be done from the office; other items are less important and not worth dealing with from the road. So my e-mail inbox is stuffed to explosively-dangerous levels, the desk piled high with papers needed attention, and the voicemail is, well, happily minimal. E-comm has, for me at least, almost entirely replaced the phone over the last decade or so.
A couple of coding themes have popped up, though, from reading clients' code and e-mail from various correspondents.
First is an increasing trend I'm seeing where developers rely on an exquisite knowledge of precedence rules in C, usually inside of if statements. A generic example:
if( variable1 operator1 variable2 operator2 variable3)do_something;
Absent parenthesis to group elements of this expression, the result may be very surprising. The statement:
if( variable1 & variable2 == variable3)do_something;
probably won't do what is expected. Ditto for:
if( variable1 < variable2 < variable3)do_something;
I strongly believe in using parenthesis in any instance where there is the slightest possibility of confusion. Cost: zero. Benefit: possibly saving a lot of debugging and maintenance time.
(In fact, the code I read while traveling incorrectly combined operators and was the source of a long-lurking bug. That "exquisite knowledge precedence rules" was sorely lacking. There's a lot of complexity to the C standard, and it's a bad idea to assume one's own perfect understanding, or that of a colleague or future maintainer).Another construct that keeps surfacing looks something like:
#define TIME 28*60 // Comment of some sort // This value may not exceed // 1800, for some reason
The good news is that the max limit is carefully commented. Assume that
TIME is defined in seconds; 28*60 is not a bad way to express 28 minutesin a clear way. However, this construct puts the burden of proving28*60 < 1800 on the developer; later hurried changes, say editing 28to 31 to meet some requirements change, will bust the limit. Add this:
#if TIME > 1800 // Enforce the 1800 second limit #error TIME exceeds 1800 seconds#endif
Now the compiler will enforce the limit. (Some may encode the 1800 into its own
TIME is a terrible name; since it has units, those units shouldbe encoded in the name so later code doesn't confuse seconds withminutes, hours, or fortnights. Better:
TIME_SECONDS . (I was at an Adaconvention in Berlin on this trip; the careful use of Ada's strongtyping makes such a mistake impossible.)
Finally, frequent correspondent Bandit sent this link: http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/.Turns out, a scary number of developers can't construct the simplestprograms in an interview test. Frankly, at first I thought the article atroll as such incompetence seems unlikely. Readers' comments though, inmany cases prove the thesis.
Surely readers of Embedded.com are far more capable than that article suggests.
Jack G. Ganssle is a lecturer and consultant on embedded developmentissues. He conducts seminars on embedded systems and helps companieswith their embedded challenges, and works as an expert witness onembedded issues. Contact him at . His website is.