Today, I'd like to add my own noise to the furor, not with any real hope of improving the situation, but mostly just as a way to vent.
Joel is right, in a very limited sense: code, left to its own devices, running in a vacuum with no changes to requirements or the surrounding platform, does not rust. However, the vast majority of code will refuse to obey such harsh restrictions.
OS upgrades and patches are released which, despite massive vendor effort, break certain apps. Sometimes buggy behavior at the OS/platform layer is deeply intertwingled with the app code, and fixing the bug in the platform actually introduces new bugs in the app. Sometimes protocols are revised, standardised, or simply created. More often than not, the customer comes back with a new set of demands and the spec of the entire application may need to be changed.
Once the variable of change is introduced, code becomes hideously fragile. The road to IT-nirvana is littered with the burnt-out husks of shattered maintenance programmers, whose sun-bleached bones rattle their skeletal fists, and say, "Damnit, Joel, code does too rust, you moron!"
I'm not quite to the point of being a permanent calcium deposit, but at times I feel close to death. I can't be too specific with details for the moment, although I hope to share some nice juicy horror stories in the coming years, as the situation becomes less delicate.
So, suffice it to say, when you can successfully remove over 1300 lines of unused, dead code from a header file, your code is officially rusted.