How often have you been here?
You’re given an archive to unpack; something to port and run and see how high it gets before it crashes. What you find is a bunch of nested directories full of source code. There’s a makefile or a project file, maybe a directory called ‘doc’ and a ‘readme.txt’ explaining some obvious stuff, but you don’t go there. Instead you open up ‘include’ and find a file named something like ‘types.h’ and see that the very first line of that file is:
#define INT int
and a little farther down is the clearly dubious
#define FOREVER while(1)
… and you confirm that you are in a world of hurt when you encounter
#define FI }
It’s not code smell. What experience has taught us to pay attention to is the involuntary little cold shiver we get in the presence of evil.
It’s gonna be another FORTRAN day. How often have you wished Moses had written a bunch of extra commandments, just for programming?
Desperate homeowners who are trying to sell their underwater mansions will sometimes bake cookies before an open house in order to entice potential buyers at the subconscious level. Likewise, outhouses have a distinct and unpleasant odor indicating that they are full of stuff that is not good for you. Smells send deep, terse and very effective messages to some of the oldest processing hardware we own, namely the bit of our brains responsible for smells. The “smell brain” belongs to one of the oldest parts of our brains, in an evolutionary sense, and smells are a great way to for us to quickly and efficiently summarize things like “The last time your great-great-great-grandpa Thog smelled what you’re smelling right now, half his tribe got eaten by something really impolite, so it’d be a good idea to leave really fast right now.”
What does this have to do with software?
I hate the term “code smell.” It seems so unprofessional. I mean, you walk up to a piece of unfamiliar code, take a peek and pronounce it as either poop or freakin’ Turing Award material in a minute or two?
Desperate developers who are running on too little experience and insufficient intellectual horsepower will sometimes try to skate by on poor design and bad quality issues by pretending to know more than they actually do. When I can’t see the core logic for all the factories, singletons, fly-weights, visitors and inheritance crap, I get the feeling that someone has “baked cookies”, and when I look at the details, often the core of the code in question is exposed as a rat burger, grilled over a burning outhouse and smothered in long expired kimchi.
The reason I hate the smell analogy is that while real-world smells can universally encode “it’s time to run like hell, but first leave some of your feces behind,” this is not universally true with code. For all but egregious examples, with code smells you need a practiced nose. It’s not a question of “Pasta or Poop?” but rather “Cabernet, or Night Train?” And depending on the task you have in mind, Night Train might do the job just fine.
So you usually can’t go to your lead and say, “This stuff is rotten, fire this coder and erase their work from the face of the earth before there is more catastrophic damage” because most managers will just see curly braces in the right spots and not get down and really try to understand the inner sickness of a diseased hunk of software that is ready to metastasize its putrid API all over the soul of your project. Your bad attitude is easily mistaken for “Not Invented Here.” And your lead might be right, too. Sometimes just rebooting the damned server every eight hours works.
Here are my top five bad portents.
1. Fucked-up looking code. Things like inconsistent brace style and indentation, declaring things (types, variables, and especially parameters) that aren’t used, mixed use of tabs and spaces, bad names, and comments like the classic “increment i” and “print result” and “harry loves lucy.”
2. Mixed error handling strategies. For instance, half the code returns a simple BOOL result in case of failure, the other half returns some set of enums or #define’d error codes, and probably someone is throwing exceptions around all of that. Mix in a healthy dose of some functions returning ints, others unsigned values, others leaving errors around in globals (yes, errno, I’m talking about you) and you’ve got a good idea of why there’s no literary prize for programs, just halfway houses and work release programs.
3. Design pattern overload. If I were king I’d just start beheading people for writing factories that make factories. It’d collectively save us billions of dollars. And every time you make a singleton, God kills a start-up, two if you think you’ve made it thread-safe.
4. Anything that claims it is standards compliant. A comment like “This implements X.509 cert cracking” means that you should go fill your Super Soaker with a 50/50 mix of holy water and battery acid because you’re going to be hosing down demons and crazy undead-bugs until the sun goes out (and I mean entropy out, not just sundown). Working with an ISO networking standard? Save time by jumping off a high place onto someone in management.
5. Abstraction layers that just pass the buck, with each layer adding, recomputing, removing or re-arranging parameters. Abstractions are like peanut butter; a layer or two is fine, but once you’re down five or six layers and nothing has fucking happened yet you’re in definite “even if I could get my mouth open to scream now, that would just let in the evil stuff I’m swimming in” territory.
Sometimes Night Train will do the job, but that doesn’t make mornings any more pleasant.
Does anything else send waves of cold up your spine?