A Word of Caution

February 1st, 2006

There’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.

Live Preview or Die

January 30th, 2006

Taking a hint from sjk in a previous comment on this blog, I have added a “live comment preview” functionality, exactly like the one being used on Hawk Wings.

The plugin is called, accurately enough “Live Comment Preview,” and was written by Jeff Minard and Iacovos Constantinou. It installs in true WordPress style – simply download the php file to the WordPress plugins folder and activate it. I think the result is quite impressive and functional. Try it out and let me know what you think!

Thanks to sjk for the suggestion and to Tim Gaden for the pointer to Live Comment Preview.

Universal Appeal

January 27th, 2006

Today I’m posting two updates: a minor revision to FastScripts, and a major version upgrade to Clarion.

In addition to more tangible features, both FastScripts and Clarion are now Universal – tested on a Core Duo iMac. To Apple’s credit, I spent more time getting to the iMac (I don’t own one yet – waiting impatiently for the MacBook Pro) than I did testing or fixing bugs. The only issue encountered turned out not to be an Intel issue at all, but rather a gcc 4.0 bug fix that causes a serious incompatibility with some gcc 3.3 code. Everything else “just worked.” Go Apple!

Clarion 2.0
This long-awaited update brings a new icon and a massive overhaul of the preferences system. With the addition of named settings, you can easily switch between dramatically different setups from the main quiz window. By defining custom configurations, your practice time can be used to focus on the specific timbres and tonalities you need the most help with.

FastScripts 2.2.8
FastScripts (and FastScripts Lite!) received a couple usability improvements:

  • The “merged folders” behavior of the script menu can now be disabled. This can be helpful for keeping the system-installed scripts visually separate from user scripts.
  • Selecting a folder from the script menu now opens that folder in the Finder (or Path Finder).

Though I don’t have my Intel MacBook Pro yet, I’m sure that once I do I’ll start resenting developers who haven’t “gone native” very quickly. Here’s to hoping I haven’t gained any Intel-owning enemies over the past few weeks! The next beta release of FlexTime will also ship as a universal binary.

Easy Endian-ness

January 25th, 2006

A lot of my readers have noticed that this blog covers extremely geeky programming topics that often fly right over the heads of less technically-submerged people. It’s not an intelligence thing – it’s all just jargon and experience. So every once in a while I’d like to pull my head out of my assumptions about who is reading the blog, and tackle something considerably more “simple.” Topics that you must understand if you’re a developer, and may want to understand as a curious non-developer.

Tim Gaden points out on his Hawk Wings blog that the term “endian-ness” has become widely used in the Mac community, and it’s leaking out of the labs and into common conversation with customers. He astutely observes that many people haven’t got the foggiest idea what it means.

In the context you’ve probably been hearing it lately, it has to do with differences between two computer chip architectures – particularly Intel and PowerPC.

PowerPC is a “big-endian” while Intel is “little-endian”.

A hexadecimal (hex, base 16) number uses the numerals 0-9 (like decimal) but adds the letters A-F, so it can represent larger numbers with a shorter number of characters. Other than that, it’s constructed like a normal decimal number, when talked about and written by humans. For instance, here’s a hex number:

0x11ff

(The 0x at the beginning is common shorthand for “this is a hex number”).

On a PowerPC system, that is exactly how the number is stored in memory. The “Big End” is the end farthest to the left. This is what you’re used to with decimal numbers. It’s why 3,000,000 dollars is a lot of money. Because the characters that “mean a lot” are on the left. On an Intel machine, the number is stored “with it’s little end in first” – so it looks backwards:

0xff11

As a very practical example, let’s say I run a program that stores a directory of all my friends. It was written for a PowerPC computer, and as part of its data format, writes the total count of friends as a number:

0x0001

You don’t have to be an expert with hex numbers to guess that the “logical value” of this number is ONE. Now, what happens when this program is run on an Intel machine? If it just reads it verbatim from disk, it ends up looking exactly the same in memory as it did on the PowerPC, but it means something completely different. Since the “little end” goes in first on an Intel machine, the number is interpreted backwards, and becomes equivalent to this PowerPC-based value:

0x0100

So instead of 1 friend, the program running on Intel thinks I have 256 friends. Hey, I like this byte-order problem! But when the program proceeds to try reading those 255 non-existant friends from disk, your data format is hosed, and the application either crashes or behaves very strangely.

The solution for most of these problems is something called “byte swapping.” This makes it the responsibility of the programmer to ensure that bytes that went to disk on whatever architecture come back into memory in the appropriate format for the current chip. A byte on a computer is exactly the amount of data that uses up two characters in a hex number. So using the above example, the bytes in question are “0x00″ and 0x01”. If the bytes went to disk in big-endian format (0x0001), they need to “trade places” when they’re read back on Intel, so that they still mean ONE in little-endian (0x0100).

Apple has done a lot of the work for developers in this transition. Thanks to the growing use of highly abstracted data formats, Apple was able to handle the grunt work for things like preferences storage automatically. But for developers with custom data types, who have not planned for endian-ness issues, the announcement that Apple would be moving to Intel was a major wake-up call. They’d have to revamp their data storage and retrieval strategy so that they were always capable of “doing the right thing” regardless of the architecture. For most Mac developers, this means “assume it’s always big-endian, and byte swap if necessary.” This assumption might change over time if little-endian processors like Intel’s end up being what the Mac sticks with. But for the time being, assuming big-endian means that the data formats can be passed seamlessly between existing applications and their Intel-savvy counterparts.

The length of even this “easy” overview of endian-ness proves that it’s actually a complex and difficult concept. I have barely scratched the surface but I hope this helps put things into a bit more perspective. The next time you hear geeks yammering on about endian-ness, perhaps you’ll have a quip or two to interject!