And I'm Having Fun...

C/C++ Users Journal July, 2004


I've been playing with an interesting new toy. About five months ago, you may recall, I described a new dialect of C++ being developed by Microsoft. Originally called Managed C++, it features a coherent set of language extensions designed to support programming in the multilanguage .NET environment. It's not unfair to characterize .NET as Microsoft's answer to Sun's Java environment. Instead of writing in Java and running portable executables safely on a Java Virtual Machine (JVM), you write in one of the .NET languages to produce a portable executable for the Common Language Interface (CLI). Both approaches share the common goals of improved security, portability, and interoperability between programs. And both offer a rich and growing set of support libraries to ease the programmer's burden.

As I reported earlier, Microsoft has submitted several aspects of their .NET environment for ECMA, and eventually ISO, standardization. Managed C++ now follows in the footsteps of C#, the flagship language of .NET, and the CLI. Along the way, its name has morphed into C++/CLI, but the goals remain very much the same. The idea is to make it possible for you to write programs in C++ that take full advantage of the CLI, and interoperate as first-class citizens with programs written in C# and the other .NET languages. More than that, C++/CLI is designed to support the natural idioms and features of this Java-esque environment, while still remaining highly conformant to the C++ Standard. Ambitious goals.

Well guess what, they seem to have succeeded. I've written over 8000 lines of code in C++/CLI during the past few weeks, and I have to admit that the exercise has been mostly downright fun. If you've ever written code in Java or C#, you understand the liberating effect of a simple language with a garbage-collected heap. You don't have to worry about dangling pointers or failing to delete unused objects—all that's handled for you by the garbage collector. On the other hand, if you've ever written code in C++, you understand the beauties of deterministic destructors for managing resource acquisition and release—all of that's still available when you need it in C++/CLI.

Code written in the managed subset can be shared with other languages, or other "assemblies" written in C++. It executes in the CLI environment that eliminates many of the botches that lead to system crashes, or that are exploited by virus makers. When you work in that environment, you think more like a Java or C# programmer, which is both good and bad, of course. C++ is already notorious as a multiparadigm language, which is a polite way of saying it's a mongrel lacking in any form of doctrinal purity. That, too, is both good and bad, of course.

But here's the real kicker. By a judicious extension of the rules for overload resolution (which were already complex), this new dialect even lets you write code that looks like ordinary C++ but that executes in the managed environment. If you've ever tried to convert a C++ program to Java, or conversely, you will understand that this is no small accomplishment. C++ is mostly a value-oriented language, manipulating objects in static storage, on the stack, and on the heap. Java and C#, by contrast, are mostly object-oriented languages, manipulating scalar objects on the stack and all user-defined objects on the heap. Those heap objects are referred to via disguised pointers, known variously as "handles" or "references" (not to be confused with the references of C++, which are different). Making all those accesses to objects through handles look like value manipulations is where C++/CLI really shines.

And here's the proof of the pudding. My little chore is to rewrite all the containers from the Standard Template Library portion of the Standard C++ Library in a form that can be shared in the managed environment. It hasn't always been easy, what with learning a new dialect and working with a compiler still in beta testing. But so far I've got working versions of vector, list, deque, map, set, multimap, and multiset. They all meet the same computational complexity requirements as the original STL (with one or two minor exceptions), and they all look very much like their unmanaged brethren. More important, the iterators they use are also managed objects on the garbage-collected heap, but they behave for all the world like conventional STL iterators. And that means that all the STL algorithms work unchanged with the managed containers.

I don't take credit for the language design, or the original spec for these new containers. Several bright folks at Microsoft deserve the kudos for all that. I'm just the implementor. And I'm having fun.

P.J. Plauger
Senior Contributing Editor
pjp@plauger.com