A Word of Caution
February 1st, 2006There’s an epidemic among programmers of “warning obliviousness.” That is, simply choosing to ignore the highly pertinent warnings that emerge from the compiler as it passes through your source files. This nasty habit not only risks masking bugs in currently shipping products, but leaves the door wide open for future bugs to worm their way into code. I’m frustrated and appalled by the number of projects I’ve worked on (or simply compiled) where a “clean build” consists of dozens or hundreds of warning lines followed by a friendly “Build Succeeded.” That’s a bald-faced lie!
In general it is a good, no a great idea to maintain warning-free source code. Warnings keep you out of a great deal of trouble. To that end I usually configure my projects such that most if not all warnings are enabled in the compiler, and that warnings are to be treated as errors. This can be annoying and cumbersome while prototyping ideas, but it’s always a good idea for at least your “Release” build style. While following this advice might not literally save your life, it will ultimately give you more time to enjoy the finer things that exist outside of your debugger.
In a follow-up post, I’ll share an amusing story about how I recently fell into the clutches of warning obliviousness, and was lucky enough to come out unscathed (after a several hours long battle with a vexing bug). In this post, I’d like to talk a bit about a possible real-life cause of warning obliviousness: fake and stupid warnings.
We are desensitized to bits of advice labeled “warnings,” due to the outrageous abuse of the term in our everyday lives.
Some of the fakest warnings are the insanely long paragraphs that fill product labels and explain in a roundabout way that “real bad stuff” will happen if you misuse the product. The thing that makes these warnings fake is that they fail to describe a real cause or a real effect. I’m looking at a package of Fisherman’s Friend cough drops. The warnings on this package take up more than half of the text on the package, and after forcing myself to read through the whole damn thing, I now know that I shouldn’t take these simple menthol drops for chronic emphysema, sore throats that last more than 2 days, or sore mouth problems that last longer than 7 days. Phew! Glad I know the magic numbers! How are intelligent people supposed to cope with this kind of warning overkill? The package should say: “Warning: This product is exceedingly safe for treatment of common symptoms, but don’t let that stop you from visiting a doctor about your serious life-threatening illness.”
How about those little “silica gel packs?” The desiccant packages come with a variety of products where manufacturers want the product to stay dry until it gets to you. We’re so familiar with them that we often joke about the “Do Not Eat” warnings that are always included. Did anybody ever really think it was OK to eat them before the warnings were put on? Hmm, I just got a new leather purse and what do you know – it came with a fun pouch of edible sand!
On my bathroom sink I find two warning-laden products: Colgate toothpaste, and SoftSoap liquid soap (also by Colgate). Each of these contains warnings to “keep out of the reach of children under 6 years of age.” Or else what? They might squeeze it into their ears and go deaf? 7 year olds are immune to the allure of dangerous bathroom products? I guess we’re supposed to assume that kids under 6 will eat anything, but isn’t that part of baby-proofing a house? If you are running around looking at all your products for this wisdom, you’re in a sad state: “Hmm, the shampoo doesn’t have a warning, honey! So it must be safe for little Billy to eat.” The toothpaste includes an additional warning: “If more than used for brushing is accidentally swallowed, get medical help or contact a Poison Control Center right away.” The vagueness of both the quantity and the outcome are ridiculous. And excuse me, but I am not in the habit of swallowing even the amount I use for brushing. And how exactly would swallowing more than that be classified as an accident? Whoops, I did it again!
Incidentally, both the SoftSoap and the toothpaste include a chemical called triclosan. The toothpaste, which goes in your mouth, contains about three times the amount as the soap, which goes on your hands (“Warning: For external use only”). On the toothpaste it’s identified as an “anti-gingivitis” agent, while its bacteria-busting attributes are proudly highlighted on the soap. I guess people who market toothpaste don’t think “Antibacterial Toothpaste – Three Times Stronger than Soap!” has a strong ring to it.
I have to give some credit to Proctor and Gamble, whose Dawn dishwashing soap contains a brief and rather meaningful paragraph of advice. “If Dawn gets in eyes, rinse thoroughly with water. If swallowed, drink a glass of water to dilute.” And to their great credit, they don’t label these tidbits “warnings” at all. Because they aren’t warnings, they’re post-accident advice. A warning is “Don’t drink Dawn because it will make you feel funny and you’ll have to dilute it with water.” I guess Dawn realized they didn’t need to give that warning, because doing so would be stupid, and therefore make customers think that Dawn thinks they’re stupid.
It’s hard to draw a line between fake and stupid when it comes to warnings. You can always argue that somebody out there needs the warning on the product in order to use it in a safe manner. Then again, my kitchen knives aren’t engraved with “Warning: Don’t stab self,” (yet?) and I seem to be getting along just fine.
Even the warnings that could be really meaningful, I’m often left with less useful information than I should have. In the case of poisons, it’s almost always something along the lines of “WARNING: Do not swallow. May cause light-headeness and nausea. Contact your poison control center immediately.” This makes it difficult to tell the difference between “poison like arsenic” and “poison like a Gin and Tonic.”
So when programmers come in from the storm of everyday warnings and look at their compiler, chugging away and spewing warnings left and right, it must feel very natural to ignore them. “Take this curve at 30 miles per hour.” Uh-huh. “Hold railing while climbing stairs.” Oh-yeah. “Do not wrap babies in plastic bags.” OK. “Installing this program will render your computer unusable.” Great! “Undefined function: DoImportantStuff()”. Yeah, whatever.
At least in real life, there is a system in place for escalating warnings to a higher, harder to ignore level. Police and ambulance warnings are accompanied by flashing lights and sirens. These mean “get the hell out of the way” and most people still take them pretty seriously. In the programming world, we only get one grade of warning. Why is that? Because every warning falls into the same category from the compiler’s perspective: “might cause a bug, but heck if know.” In this way the compiler warning is sort of a fake warning, because it doesn’t describe a real effect. But it’s a cry for help. The compiler needs us, the brilliant engineers, to intervene for the well-being of the program and its users. When you ignore these warnings, you’re letting your compiler, your users, and yourself down. And you’ll pay dearly for it one day.
February 1st, 2006 at 4:23 pm
Remember kids, -Werror is your friend!
February 1st, 2006 at 4:38 pm
Amen.
February 1st, 2006 at 7:12 pm
1) The reason why those Fisherman’s Friend lozenges spell out the details (# of days, etc) is that many people don’t know when some problem is serious enough to require medical attention. Especially if a visit to a doctor is going to cost them $$$, they might be inclined to just cover up the symptoms by using those lozenges.
This is analogous to the situation with many beginning C programmers: Stupid compiler is warning me about mismatched types, I’ll just add a cast to shut it up.
2) Some of those desiccant packets contain toxic indicator chemicals (see: http://en.wikipedia.org/wiki/Silica_gel). And there were unconfirmed reports that some Afghans were eating the desiccant that came in the food drops in 2001 – the warning labels were not in any language that they understood.
February 1st, 2006 at 11:26 pm
Let’s not bend over backwards imagining legitimate reasons for all those product warnings. They’re not there for the consumer’s benefit. They’re there so a company lawyer can point at them and say “We did everything it was reasonable to do to protect the consumer.”
P.S. Packing dessicant with food does seem pretty stupid.
P.P.S. Do not taunt Happy Fun Ball.
February 1st, 2006 at 11:39 pm
Some compiler warnings can be ignored – or at least tolerated. If I really do want to do something like
if (i=1){};
and it thinks I may want to doif (i==1){};
, then I can safely ignore the warning. This is not exactly the best example, but I know I’ve seen warnings that looks somewhat like this.BTW, the Enable live preview checkbox is as wide as the Submit Comment box on Firefox Mac.
P.S. At the bottom, it says:
Is there a prize for the 32,768th visitor?
February 2nd, 2006 at 6:50 am
Then there’s the mysterious warning on Preparation H, cautioning people not to use it if they’re on anti-depressants. Huh?
Or, so I hear anyway.
February 2nd, 2006 at 7:46 am
I’m really sad to hear about people actually eating silica gel packs.
Matt: I absolutely disagree about ignoring “some warnings.” It’s a major part of my complaint – once you ignore a single warning it becomes a slipperly slope and unarguably evil warnings will slip in.
For the example you cite, the warning from gcc is “warning: suggest parentheses around assignment used as truth value.” And it’s great advice. How do you fix it? Just follow the advice. You end up with “if ((i=1)){};” which looks kind of goofy, but you know what? You’re doing something goofy. :) So you put the double-parens in to a) quiet the compiler and b) remind yourself later that you meant to do something goofy there.
Do whatever it takes to quiet the compiler! Or you won’t be able to tell when it’s not crying wolf. In the worst case scenario, I would even suggest turning off particular warnings so that at least you can see when your code goes from quiet to noisy to for the particular set of enabled warnings.
Looks like visitor 32,768 came while I was sleeping. Alas! I should probably take that line out anyway – it came with a plugin I put it in when I started the blog and I’m not sure how accurate it is.
If you have ideas for how to fix the “Enable live preview” checkbox width, please comment on on this entry. Thanks!
February 2nd, 2006 at 4:57 pm
Hmmm, whilst I’m all in agreement with you about warnings, they’re not that easy to eradicate if you don’t understand them. I’ve recently been perplexed by some new warnings introduced to previously find code by gcc 4 about pointer-signedness. Sadly, I can’t track down any helpful information about how to fix the damned thing. So for now, it stays that way, until my knowledge increases… But it sure does irritate me knowing that warning is sitting there!
February 21st, 2006 at 4:49 am
Hi, I do agree, but also _some_ compiler warnings are plain stupid.
The Compiler we use at work, gives warnings for unused routines (dead code) and worse, routines that will not return control (error routines where you just want to give up and exit). The SQL plugin warns on DELETE without WHERE condition.
The first two are often used for included error-handling-code, the last is the way to go for reused temporary tables. The first two can be worked around (but the resulting code is ugly) and the latter forces you to occasionally check the full compiler output, if anything serious has happened.
Anyway you are right, but interactive compilers would be much nicer in any way. I think of something integrating with an editor (like SubEthaEdit) adding comments: “You know that case will fail if…” and you can say. “Yeah, I checked that, don’t warn me again for this occurrence”
Cheers, iSee
February 21st, 2006 at 11:40 pm
Another desiccant anecdote:- A Japanese friend of mine when I was living in London gave me a packet of Japanese green tea. There was a tiny sachet inside the pack of tea with various cool symbols in Japanese. I assumed it was some kind of flavouring and added it to the tea and served it up to all my friends. The tea tasted disgusting (ultra-bitter), but we just assumed that it was an acquired taste and drank several cups each. The Japanese friend told us afterwards what the pack was and I never made the same mistake again.
February 21st, 2006 at 11:46 pm
WARNING: EXTRANEOUS APOSTROPHES DETECTED!
1.
it”™s bacteria-busting attributes are proudly highlighted on the soap
should be
its bacteria-busting attributes are proudly highlighted on the soap
2.
So when programmer”™s come in from the storm of everyday warnings
should be
So when programmers come in from the storm of everyday warnings
February 22nd, 2006 at 7:46 am
Thanks Rickla for the funny anecode and for the corrections. You’ve discovered my “sounds like dummy” weakness! :)
March 11th, 2006 at 11:24 am
I like the idea of -Werror, but unfortunately I rely on stuff such as …
“#warning remember to do something really important here when you get round to it”.
If someone can suggest a better way of doing that Ill flip the switch.
March 11th, 2006 at 1:50 pm
Jamie – I suggest coming up with a convention for comments for TODOs, like “//TODO: remember to …” and then using the ‘Find in Project’ command to keep track of them. That works for me, and got me off the habit of using #warning as well…
March 11th, 2006 at 4:10 pm
I use a variation on the “source tagging” technique suggested by Mike. For historical reasons, the tag I use is my initials surrounded by bullets: -DCJ-. This has the advantage of being absolutely impossible to be mistaken for anything else, but did manage to expose an annoying bug in Xcode.
Of course it doesn’t have the same “constant reminder” advantages of the #warn technique, but perhaps some a clever shell script could scan the sources and produce a reminder of all such items when a “Release” target is being built.