Defensive Programming
Jan. 18th, 2005 10:50 pmI'm currently reading Kernighan and Pike's The Practice of
Programming, which
jennyaxe bought for herself quite
some time ago. Mostly, I've found it quite informative and useful.
Then, today, I reached the bit on defensive programming. And dude, are misters Kernighan and Pike not at all sysadmins. Their idea of defensive programming doesn't go much further than having functions check that the arguments they get are basically non-insane and putting assert()s at strategic points. Which are things that most programmers really should do a lot more of, don't get me wrong there. It's just that after a bunch of years as a sysadmin, my idea of defensive programming includes things like this (except most often in Perl):
if(i==0){
/* do something */
} else if(i!=0) {
/* do something else */
} else {
/* Toto, I don't think we're in Kansas any more */
}
I've never met a programmer who'd do it that way. I mean, on a first look it's totally pointless. Either the value of i is zero or it isn't, there is no third option. I'll admit that I started writing code like that in a fit of paranoia during a long and deeply frustrating hunt for a problem in a simulation system, and for no better reason than "Nothing strange is going to go undetected!". But in the years since then, it's happened to me twice that programs have reached that final branch. Once because of a not-so-good system library upgrade and once because of a subtly broken RAM board. Which, aside from making me feel validated in writing that sort of code, makes me wonder how many errors of that type go undetected. The machine we had with the broken RAM was also a simulation server, and if not for the impossible printout from my monitoring hack the problem might never have been detected. The most likely result of the flaw was to make the simulation produce wrong results -- which nobody would've noticed, and which in turn might've been quite bad, since what they were simulating was electronics for fighter aircraft.
(no subject)
Date: 2005-01-18 11:40 pm (UTC)And, of course, Pike et al. think nothing of rewriting every application on the system to make life slightly better, if the "right" place to fix it means everything else breaks.
But your quoted code makes me wonder - aside from languages with tri-state logic, what are you expecting a compiler/interpreter to do with your third branch? Many would chuck away both the third branch and the code to test the second variable (unless volatile or the moral equivalent). Certainly the compilers I work on would optimise this into oblivion.
(no subject)
Date: 2005-01-18 11:49 pm (UTC)(no subject)
Date: 2005-01-19 08:12 am (UTC)(no subject)
Date: 2005-01-19 10:46 am (UTC)Sigh. I spent half of yesterday on this one:
sqlinteger x;followed 50 lines down by:
f((unsigned long *) &x);Gee, thanks guys. That cast suppressed that pesky compiler warning all right -- well done! Too bad I tried moving the code to a machine where sqlinteger was 32 bits and longs were 64...