Pretty much every developer I’ve ever met (and I’d guess that it’s a really common trend in the IT industry as a whole) thinks of boilerplate code (the non-algorithmic stuff, the stuff that double-checks input values and checks called functions for returned error codes, that kind of thing) as being “the boring stuff”. We mostly tend to skip over it (or at least cover it very quickly) in college courses to focus on the algorithmic stuff because of time pressure and the need to teach the meat of things. But in yet another excellent EBSE result picked up on by NeverWorkInTheory (and if you work as a developer, you really ought to be reading that blog regularly), the actual worth of that simple boring boilerplate code comes through:
- [A]lmost all (92%) of the catastrophic system failures are the result of incorrect handling of non-fatal errors explicitly signaled in software.
- [I]n 58% of the catastrophic failures, the underlying faults could easily have been detected through simple testing of error handling code.
- A majority (77%) of the failures require more than one input event to manifest, but most of the failures (90%) require no more than 3.
- For a majority (84%) of the failures, all of their triggering events are logged.
- Almost all catastrophic failures (92%) are the result of incorrect handling of non-fatal errors explicitly signaled in software.
That’s a massively important result to have proven, to the point where it’s now going to seem blindingly obvious to everyone in retrospect! 😀 Sure, you knew boilerplate was important, but: we call it boilerplate. As in boring, humdrum, same-old-same-old, don’t-waste-too-much-time-on-it, we’ll-come-back-and-add-it-in-later code. Some of the more recent methodologies like TDD try to address this, but leaving aside the point that they’re not used everywhere, and the point that they’re not always completely adhered to, be honest with yourself for a moment, in private — before you read that paper, did you actually know with any solidity just how important boilerplate code was or how many catastrophic failures it could so easily have averted (and pragmatically, how much money it could have saved for how little investment)? Did you budget developer time explicitly to writing it (instead of cut-n-pasting it out of a reference text somewhere)? Did you test the boilerplate code explicitly?
Quick example for how pervasive this is – go search for “how to open a file in C”. Dirt simple task, several tutorials and reference pages. Go on, take a look (if you don’t like C, pick some other basic operation in your favorite language). Pick out some sample code at random. Some of it is obviously boilerplate-averse:
FILE *fp; fp=fopen("c:\\test.txt", "w"); fprintf(fp, "Testing...\n");
Okay, that’s obvious, but what about this?
FILE *ifp, *ofp; char *mode = "r"; char outputFilename[] = "out.list"; ifp = fopen("in.list", mode); if (ifp == NULL) { fprintf(stderr, "Can't open input file in.list!\n"); exit(1); } ofp = fopen(outputFilename, "w"); if (ofp == NULL) { fprintf(stderr, "Can't open output file %s!\n", outputFilename); exit(1); }
Looks better, but what happens if the logging system won’t let you write to stderr? Those fprintf() calls will fail but we don’t check their return values at all, let alone call ferror() there. Could that cause a catastrophic failure? Well, maybe not on its own, but since it would not report an error properly, it could contribute to one.
Maybe we’re being unfair here, these are tutorials after all, but that’s kindof the point – we always skip the boilerplate and assume it’ll be written in later but how many projects have you seen where chunks of code were obviously either adapted from this kind of reference or tutorial code without having the checks added in; or were entirely typed using the Control, C and V keys? And how many times have you seen the boilerplate get called every time?
I’ll admit, I always had boilerplate filed under “yeah, that’s kinda important” without any numbers being attached to it and the rider that not all of it was as important as the rest and you didn’t always need all of it in all cases (and okay, for prototype code, I still think that but I also think prototype code shouldn’t ever get into production and I’ve learnt to my detriment that it does on far too many occasions…). I’m going to be rethinking that particular attitude that after reading that paper. I’d quietly recommend you do the same…
Tags: boilerplate, EBSE, error, failure