December 12, 2004
Introspection kicks ass
- Automatic memory management
- True strong typing (C++ can be untyped if you let it)
- Cleaner semantics
- Thorough runtime checks
- Dangling pointers are impossible
- Memory corruption is impossible
- A workable alternative to the abomination of C++ multiple inheritance
I was also unhappy to loose C++ templates. Constantly having to use explicit dynamic type conversions when using container objects really irritated me and I was aware of their performance cost. That said, I preferred Java for non-games projects, where performance was not a concern for me.
But I was completely missing the point. One thing that lifts Java above languages like C and C++ (and a feature present in many other higher level languages) is introspection (also called reflection). This is an awesome language feature. Since then I have tried to emulate this feature in C++ with varying degrees of success.
Introspection is where a program is able to examine its own structure as it runs. So for example, if it has a reference to an object it can iterate over all the properties of that object, get their names and values and then save them to a file. This has all kinds of useful applications for games. It can be used for loading and saving game state, meaning you don't need to write any per-class serialization code. A level editor can use it to provide a view of the game state to a designer, who can then edit it. It can be used to automatically synchronize game state in a network game, etc, etc.
This may not seem like such a big deal. Writing explicit code to do all this stuff is pretty straightforward. But having used introspection, I understand that this is the code that causes a lot of the friction when you are mid-way through a large project with a large team. When that code just works, everything goes much more smoothly.
It's like inheritance on steroids. When I started out with OO programming, the idea that I could just derive from another class and get all of it's features for free amazed me. With introspection you can reuse other code but in a way that cuts straight across the class hierarchy. For example, if you want to be able to load game state from a file, you write some general purpose code that knows how to serialize a graph of objects by examining their state through an introspection API. Having written that general purpose code, any object that conforms to the object model expected by the serialization code can be loaded from a file.
Some things have changed since then. We are far less concerned about performance than we were then. The higher level languages have matured a lot. They have really good IDEs and tools. Java even has templates now!
So I'm not saying we should all abandon C++ for Java. That is not a good idea or even feasible. C++ is an excellent language for all kinds of things:
- It is essential for interfacing with a platform or 3rd party middleware having a C or C++ API.
- Depending on the performance characteristics of the platform, although some code may be better expressed in a higher-level language, it may be better implemented in C++ if it has a significant impact on performance.
- It is essential for certain pedal to the metal things like writing DMA interrupt handlers.
- If I want some code to go as fast as possible and I have a good understanding of my platform's hardware, C++ is an excellent alternative to assembly language.
Neither am I saying we should immediately start using Java wherever it is appropriate. Java was just an example. There are many excellent languages that could fill roles as higher level languages in games.