Objective-C for C++ Programmers, Part 1
Regular readers will know that I spend a lot of my time these days writing Objective-C code. Now that I've finished writing a Smalltalk compiler that generates code where the objects are toll-free bridged with Objective-C objects, that situation might change. In the meantime, however, this article will provide an introduction to Objective-C for people who are more familiar with C++.
Objective-C was designed as a minimal set of extensions to C providing Smalltalk-like semantics. It also included Smalltalk-like syntax, which makes it easy to see which bits of code are pure C, and which bits contain the Objective-C extensions.
Unlike C++, Objective-C is a pure superset of C. Every C program is a valid Objective-C program. All of the new keywords in Objective-C are prefixed by the @ character, which is not valid in C identifiers.
The Runtime System
The first implementation of Objective-C was a preprocessor, which turned Objective-C into C. The dynamic features of the language were all supported by a runtime library. Modern compilers don't use C as an intermediate language, but they still have the same arrangement with a runtime library providing dynamic features.
In Objective-C, objects are just C structures with the first element being a pointer to another C structure representing the class. Exactly what this class structure contains varies a little bit between runtimes, but at the very least it contains the information required to look up methods, the layout of the instance variables ("member fields," in C++ speak) and some other metadata.
Since Objective-C is a pure superset of C, and all of the features of the runtime library (including the structure of classes) are exposed to C, this means that Objective-C fully exposes the object model to the programmer. There's no "magic" in Objective-C. When you call a method in C++, the compiler does some complicated things with vtables to find the correct code to run. In Objective-C, it does one of the following:
- Calls a C function to look up the function that implements the method (with the GNU runtime)
- Calls a C function that looks up the method and calls it in one operation (with the Apple runtime).
This means that you can write pure C code that interacts with Objective-C objects. It also allows you to bypass some of the dynamic behavior at times when it's not needed.