I’m reminded now about the virtues of singular exits – that is, functions with only one exit point. I was a bit lazy while writing the FAT driver code, and put in a bazillion exit points. The only thing that was really surprising about that, in hindsight, is how long I managed to get away with it before it came back and bit me. I’ve just spent a few hours debugging a problem where an allocated block wasn’t being freed, and of course it turns out there was an early exit that I’d added recently which didn’t do the proper cleanup.
And it wasn’t even really an erroneous scenario, this early exit – it’s quite likely we would have encountered it in real world usage. Good thing I test my code occasionally. ;)
I’ve started rewriting the FAT driver stuff to fix this problem, but I really should have done it properly to start with. Rewriting introduces new bugs – I’ve already created, found and fixed several – which should have been avoided.
It reminds me of the colossal effort that’s been required to rerwrite the older portions of the Keychain framework. So much stuff in there was written when I was still unfamiliar with Cocoa, and there’s weird things in there – like retaining local variables, for example, which now of course I realise is just bizarre. Or the gratuitous use of C strings instead of UTF8 strings (plus the associated issues of NULL parameters to strlen and friends). A lot of time has been wasted doing this refactoring. Of course, in that case there’s not much I could have done to avoid it; it takes time to learn these things. I guess the lesson that could be taken away from this case is that you shouldn’t take on long term or ongoing projects while you’re still learning, lest you get stuck having to support the crappy code you wrote.