Monday 26 January 2009

Not all assignments are equal: = != ==

C, for all its brevity, is a minefield for the unwary.

One of the more irritating gotchas in the lexicon is that:

if( x = 10 )

is perfectly correct C, and will compile and run perfectly happily. The preprocessor will not squint at it, the compiler will look the other way, the linker will care not a jot. And yet it is almost certainly wrong, as it is an assignment rather than a test for equality (that is, it sets x to 10, rather than testing if x is already equal to 10).

What was probably intended here was:

if( x == 10 )

Grizzled veterans (by which I mean those who've been bitten often enough by this particular gotcha) avoid the whole issue by writing:

if( 10 == x )

This is a neat approach, as this code will not compile if you accidentally try to perform an assignment:

if( 10 = x ) // compiler error

This is a good sign in an interview candidate, as it displays both an awareness of the problem, the natural cunning to work around it, and the self-awareness to admit that they won't always get it right.

I still fall prey to this occasionally, despite being fully aware of the issue. Perhaps once every two years, while tracing some random weirdness in my code, I'll be stepping through the source in the debugger when I see the dreaded accidental assignment of doom. At this point I generally curse, make a mental note to kick the cat when I get home, and quickly fix the offending line before anyone can see it.

The problem is that the part of my brain that does maths rebels at the 'backwards' statement 'if 10 equals x'. It just looks ugly and wrong, despite being the 'smart' thing to do. I do actually do it, but I have to force myself to, and it always feels a bit clunky. And because it feels a bit clunky, I sometimes submit to my natural tendency to write it the other way round.

In my daily work I tend to rapidly context switch between C, C++, Delphi, and Perl. Delphi is particularly nasty in this respect, as in it '=' is the test for equality. I suspect that I generally make this mistake on switching from Delphi to C/C++.

Tuesday 20 January 2009

Why You Should Spell Check Your Comments

A couple of years ago we had our boiler replaced. We had the incumbent traditional boiler replaced with a combi boiler, which has behaved (more or less) impeccably ever since.

This is a fairly substantial operation, involving the removal of the previous boiler, hot water tank, expansion cistern, etc, and the installation of the new boiler itself. Our guy recommended putting the new boiler where the old hot water tank had been, in the airing cupboard in the bathroom.

I called our mate Gav to explain all of this. Now Gav is a top bloke; likes a good curry, and extremely partial to a real ale. But more pertinently, he's a plumber and gas fitter. Unfortunately he doesn't live locally or I'd have had him in to do the work like a shot. But needs must. Anyway, I explained what we were having done, and asked him for any pointers. Tips of the trade, that sort of thing. And he said I should check what the fitter did with the pipes leading to the old hot water tank. These pipes would now be unused, and could be cut back and capped. "He should cut them right back to the floor or ceiling", declared Gav. "They should be right out of the way."

Eh? These pipes would be completely unused, hidden right at the back of a cupboard where only we might ever see them, and even then, only if we went looking for them. What was the point of cutting them right back?

"It shows he knows what he's doing, and cares about how he does it. He wants his work to be neat and tidy, even if no-one will ever see it. It's the sign of a craftsman."

And sure enough, Mike the fitter cut the pipes right back. Even though there's no particular functional reason for doing so. And I still notice this every time I open the cupboard.

---

When I review some code for a colleague, the very first thing I do is run a spell check. On both the code and the comments. And every time, it throws up a whole bunch of misspellings.

Now, the tool chain doesn't give a monkey's about how the code and/or the comments are spelled. The pre-processor blithely rips out all of the comments, and as long as the engineer spells consistently, whether well or badly, the compiler will be perfectly happy with the source code. But I care, and you should too. I also care about grammar, and about code layout. Why?
  1. Engineering is a global discipline. For many of my colleagues, English is a second or third language. I work for a global company, where people on pretty much any continent may pick up some code you've written. It's difficult enough to understand another person's code without making things even worse by mangling the English syntax as well as the code. Parsing that mess is just a waste of brain cycles.
  2. It's indicative of a professional approach. It just smacks of quality. I know of no objective research to back me up, but experience tells me that well-spelled, carefully laid-out code has fewer bugs than sloppily written and maintained code. Of course, this doesn't mean that developers can improve their code by having a dictionary to hand while programming. It's just that there's a very strong correlation between spelling, layout, and quality. Someone who cares enough to take the time to spell their comments correctly is more likely to take the time to check their code for common gotchas such as array overruns. Go figure.
  3. For me personally, it's as good a way as any of randomly vectoring into a fresh chunk of code. When a fresh glob of steaming source lands on my desk, I have to start dissecting it somehow. And when my spell check throws up a query, I go look at the offending file. As often as not I'll notice something suspect about the code in the immediate vicinity of the typo.
I don't religiously flag all typos. I recently came across a comment describing 'burst initialisation' which had somehow been transcribed as 'bust initialisation'. That was just such a beautiful concept that I had to leave it in.