Learning To Drive a Stick Shift
I’ve always thought that programmers should know how to drive a stick shift.
Pop the clutch, wrestle it into 2nd, finesse the gas, let the acceleration plaster you into those plush, faux-leather seats.
This is driving.
Now, I don’t have anything against automatic transmissions. In fact, I love automatic transmissions:
But a programmer should know, or at least be familiar with, the low-level stuff.
That means: pointers. Threads. DLLs. Import tables. Memory allocation. Nuts and bolts. Stuff that’s often abstracted away for us quite nicely by the .NET framework or the JVM. In a recent Stackoverflow.com podcast, Joel Spolsky makes the point:
But, but, but, but, but you see the thing about C is it’s not COBOL, which is the language that the old programmers used, it’s the language that is closer to the machine. And so, things like stacks, they’re still going on there, and, and malloc and memory allocation in C, yeah it’s a lot of manual work that’s done for you automatically in modern languages, but it’s done for you automatically-it’s still getting done. And so studying C, for example, is like learning how to drive a stick shift car. It’s learning how your car works, and what the connections are, and how the gears work, and basically the main parts of the drive shaft, and parts of your car. And you don’t have to know about them to drive an automatic, it’s true, but to really be a person who designs cars, or is an expert at cars, or who’s an auto mechanic, or who’s just kind of a wizard at cars, you have to know that anatomical stuff. So you’re not really-I don’t think C is an obsolete language, because it’s just an expression of assembler. It’s just an easier to use expression of assembler language. And it reflects what actually goes on at the chip
Joe, you stole my metaphor. Or rather, my simile.
The typical attitude around the development water cooler is that “you only need C++ for performance, and performance is a non-issue in most applications.” But this kind of either/or thinking misses the forest for the trees. As Visual C++ team member Stephan T. Lavavej put it in The Future of C++:
Aside from the elevator controllers and supercomputers, does performance still matter for ordinary desktops and servers? Oh yes. Processors have finally hit a brick wall, as our Herb Sutter explained in 2005 at http://gotw.ca/publications/concurrency-ddj.htm . The hardware people, who do magical things with silicon, have encountered engineering limitations that have prevented consumer processors from steadily rising in frequency as they have since the beginning of time. Although our processors aren’t getting any slower, they’re also not getting massively faster anymore (at least, barring some incredible breakthrough). And anyways, there isn’t plenty of room at the bottom anymore. Our circuits are incredibly close to the atomic level, and atoms aren’t getting any smaller. The engineering limit to frequency has simply arrived before the physical limit to circuitry. Caches will continue to get larger for the foreseeable future, which is nice, but having a cache that’s twice as large isn’t as nice as running everything at twice the frequency.
But let’s ignore the mythology that performance isn’t an issue. Let’s just admit the following truths, and hold them to be self-evident:
- That C/C++ is the most performant language in the world, with the exception of assembler itself.
- That C++ brings this performance to bear using a high-level syntax which is remarkably similar to the syntax of Java and C#—because Java and C# borrowed heavily from C++.
- That for some desktop applications, performance isn’t an issue.
But these truths have little or nothing to do with why every programmer should know C and C++.
They have little or nothing to do with why I say: if you want to be a top-notch programmer, you can no more afford to ignore the C and C++ languages than a civil engineer can afford to ignore the difference between a plumb line and a snap line, a right angle and an oblique one.
By saying that, I’m not implying that I consider myself to be a top-notch programmer. And I’m not recommending that you or your organization start or continue developing in C++ as a way of conducting business. That’s a considerably more complex question, and one nobody can really answer but you.
I’m not starting or contributing to a language war here, of any kind. Not even a minor skirmish.
No, I recommend learning C++ for the most selfless and utilitarian of reasons: learning C/C++ will make you a better programmer in your language of choice, whatever it may be.
Ruby. Java. C#. VB.NET. And yes, even Haskell. Whatever you program in: C++ will make you better at it.
Take a typical high-level programmer and immerse him for just a few months in a pot of boiling oil native C++ project:
- Processes and threads
- Stacks and heaps
- Pointers and references
- Memory addresses
- Why hexadecimal is your friend
- How strings are represented in memory
He’ll emerge leaner, tougher, and with renewed confidence in the language of the day, whether it’s C#, C++, or Ruby. He’ll know, for example, exactly what it means to push a variable onto the stack. And he’ll know why, when he tries to allocate and then start accessing an array with 2 million elements, the hard drive churns even though the machine has 4GB of memory.
And when the whole application crashes, and spits out some god-forsaken maintenance error code along with a 4-byte or 8-byte memory address: he’ll have some clue what it means, or how to go about finding out what it means.
C++ informs and bolsters your software development skills across the board by acquainting you with the nuts and bolts that underlie every language in the world, almost without exception.
So the next time you have some spare time, pick up a good introductory or advanced C++ book, dust the cobwebs off of your C++ compiler, and point the nose of that lean, mean, muscle machine out your garage door, through the quaint byways of suburbia, and up into the mountains.
You’ll thank yourself for it in the interview room.