Where I’m Coming From
I used to be very much a “C” guy. After learning BASIC and Pascal in my early teens, I cut my chops on C and – despite a few struggles – fell in love with it. The language felt right; it was close to the metal, but far enough away that programming it it could be pleasant. It helped me truly build a model of computation in my head which I think has served me well.
After getting into the web industry, however, I began to leave C behind. I coded in it less and less, since the industry outside of J2EE pretty much runs on dynamic languages (at that time, Perl – now PHP, ASP, Python, etc.). These languages always felt a little messy to me; I didn’t know what was really going on at the metal any more, like it felt like I did with C. Automatic memory management felt like a black box, and it always seemed I couldn’t optimize my data structures except at the algorithm level. And even then, who knew what the GC was doing in the background.
Over time, however, I came to embrace them – even to the point of spending a good deal of my free time playing in Lisp, Scheme, and SmallTalk. With processing power and memory becoming cheaper and cheaper, it was less necessary to worry about the overhead in dynamic languages, at least for my purposes. They tend to run plenty fast enough for web applications (where most performance problems are I/O- or DB-bound), and if they don’t then there’s always caching or throwing more hardware at the problem. If you know what you’re doing, the medium lends itself to the dynamic language programming style very well. It’s a common joke that PHP’s memory leaks don’t matter if a page request only lasts a second, and it’s basically true; who cares about optimizing a process that works to your needs? Reach the equilibrium between programmer time and project requirements, then move on to the next thing.
My old self would scoff at that attitude. It seems lazy, and it is. It still makes me uncomfortable. But it’s the way the web industry is built; the seat-of-the-pants, fly-by-night, hack-it-till-you-make-it attitude.
Where I’d Like To Go
However, I’ve got a bit of a problem. A long-time goal of mine has been to get into the PC game industry, ever since I wrote my first “Hello, World” in BASIC when I was 12. A kid getting into programming to write games is almost cliche, but it’s true; there are few teenagers that dream about writing database software or eCommerce sites. When we grow up our tastes often change, but sometimes they don’t. Case in point: after a decade in the web industry, I still want to work on real, wide-release, 3d games for a living.
There’s a small problem with moving to the game industry after the web industry, however. The programming culture is almost entirely different. The dynamic languages that I’ve mostly been immersed in at work – except for C# – are relegated to scripting in the game industry. Real developer positions, for the foreseeable future, have one almost ubiquitous language: C++.
That’s changing, somewhat, of course. Some development houses I understand are moving to C#, especially Xbox developers. Microsoft is pushing XNA, which runs on .NET. Then there are other enterprising folks who refuse to conform. But for most places, C++ still seems to be the language of choice for PC games.
So, basically, I made a choice. A while ago, I started sharpening my C++ skills again.
The Long Road Ahead
Now, in the hierarchy of languages that I enjoy coding in, C++ ranks somewhere above COBOL but below Logo; it is a complicated beast of a thing, with so many gotchas and corner cases that I’m sure it would make a Pharisee sweat. I actually derive real pleasure from the rantings of Yossi Kreinin in his C++ FQA Lite; even when I think he’s being somewhat unfair to the C++ FAQ authors, and even when I disagree with him on substantive issues, he still usually has interesting criticisms.
So, if I am so critical of C++, why am I studying it? Very simply – because C++ is still the industry language for game development. This is true just as much for historical reasons as it is for practical ones; arguably, there are better languages than C++ at the same level, without turning to dynamic or managed languages. But industry standard is industry standard, and until that tide turns, those of us who’d like to work with that industry have to tag along.
Now, I consider myself fairly proficient with C++ for someone who hasn’t shipped anything in it (it’s not exactly number one in my current field). I have most of the important bits of the language in my head, and I’m aware of things like RAII and how to implement patterns, etc. I’ve read Scott Meyer’s two books (though I haven’t fully internalized it all), and I’ve even built stuff in the language.
That said, it easily takes me up to two to ten times longer to implement and debug C++ code than in a dynamic language like Ruby or Lisp, depending on the complexity. Part of that is, of course, the language (and implementations) – no lexical closures (yet), no first-class functions (yet) (function pointers don’t count), no multiple dispatch (if you’ve never used it, it is unbelievably useful), gratuitous overloading of C keywords (like “static”), no standard ABI, private variables stored in header files (I understand why, and it can be avoided with pimpl, but it still bothers me), cryptic error messages (especially for templates, but other times as well), slow compilation…I can go on. One of the more irritating things is the default copy-constructors, and these days I just throw boost::noncopyable onto my classes unless I know consumers will need it (which is less often than you may think).
C++0x has some improvements. For example, I can’t wait for type inference; if the compiler can figure out what type I want, then why should I spell it out every time (though there are some limitations1)? Even better, we’re going to have real lambdas and closures! But who knows how long it’ll take to implement – we’re still waiting for C99. Hopefully we’ll at least get early uptake of the most important features. TR1 is already available for VC9.
Qiān Lǐ Zhī Háng, Shǐ Yú Zú Xià2
I still have a ways to go. I’m in the playing around with various projects in C++, trying to be idiomatic rather than cute or clever. At the same time, I’m going through Sutter’s Exceptional C++ and C++ Coding Standards, internalizing good habits. It’s a little tough returning to the world of static typing, (semi-)manual memory management, and complex builds after such a long hiatus, but it’s worth the rewards. A longtime dream realized—becoming a real game developer.
I welcome the challenge.
1For example, if you create a
vector<int> v, you might want to retrieve a
auto i = v.begin() will only return the most obvious type, which in this case is a plain
::iterator, and there doesn’t seem to be a way to specify an alternate. You’ll still have to specify
vector<int>::const_iterator ci = v.begin(). Oh well.