The illusion of scalability
Though designed for scalability, C++ is actually less useful than Java for building big projects.
By Bruce Eckel
I've worked with
C++ almost since its inception, and while rewriting
Thinking in C++ for the second edition, I've been reflecting on its contribution as a language. I can remember the first time I saw
a book by Bjarne Stroustrup, who created C++. I was fascinated, but rather quickly decided that it was too complicated for me to understand.
I later discovered that what I'd dismissed on first contact
was to become an important part of my life. (It was neither the first nor the last
such discovery for me; I've learned to pay attention to what I dismiss, if that makes any
sense.)
A year or so later, I unknowingly sat down at dinner next to Stroustrup at the first Usenix C++ conference in Santa Fe, New Mexico.
Still young and ignorant, I had decided that I could learn the language after all, and had gone to work for Tom Keffer
(who sent me to the conference) at the University of Washington School of
Oceanography. Most of that year was spent struggling with the language, looking at the C code produced by cfront
-- the original C++ to C translator -- and being generally confused.
Language mastery and design
Some 13 years later, after spending years attending ANSI/ISO C++ meetings (mostly to try to understand what was going on with the language), writing books and articles, consulting,
and giving seminars, I find that I'm still discovering dark corners in the language. And I
have begun to wonder if the C mentality isn't just a bit too much of an influence in C++. C programmers (at one time, I did low-level embedded programming in C) seem to enjoy the dark corners, and in a language as simple as C
they are tolerable. But add objects and everything else to C++, and the
language's dark corners become overwhelming.
In the combined November and December issue of The C++ Report, there's a
symposium called "Wisdom of the
Experts" wherein Bjarne Stroustrup, Andy Koenig, John Vlissides, and others give an overview of the issues they see in C++.
Stroustrup's and Koenig's straightforward observations come down to "know the language and use it for what it's designed for."
Sound advice? Yes, except that "knowing the language" well enough to use it properly is
really more of an objective than advice about how to get to that point. It's a goal I've been
working toward for a long time. Whenever I think I've mastered C++ sufficiently for a big project, I
learn something new and surprising -- something important -- and this
disturbs me. I usually discover that Scott Meyers (author of Effective C++) knew about it all along, but
that not very many other people did.
In contrast to Stroustrup and Koenig, John Vlissides advises, "Don't spend your life learning every last detail of
C++." Jesse Liberty similarly offers, "Focus on the semantics of what you're trying to build rather than on the specific syntactic sugar that C++ happens to require." Nice thoughts: stay high level. But C++ doesn't allow you to get away with this; you must know what's going on even when you're designing at a higher level. C++ provides a better abstraction from the machine than C, but you still have to know a great deal about what's happening.
Complexity versus scalability
The reason I bring all this up under the banner of scalability is that C++ was designed to scale up. Classes allow you to package code better, namespaces allow you to package libraries better, templates allow you to reuse some kinds of code better. The intent was to enable you to build big projects out of reusable components.
C++ is certainly valuable. I'd choose it in a heartbeat over C. I think C++ is primarily responsible for the mass acceptance of object-oriented programming
(despite the fact that lots of people are just programming in C but using a C++
compiler). It has features designed to allow it to scale, and it certainly does scale better than many languages.
I find that C++ doesn't actually scale very well, though, precisely because of
its underlying complexity and its dark corners. Most of these problems exist for
at least tolerable reasons (usually backwards compatibility with C). But the hidden cost of all these
details is that it becomes very hard to get everything right. In addition, it takes rather a long time to know what
right means.
A study many years ago discovered that people could comfortably hold about seven
concepts in their heads at any one time. Simplicity really does make a difference, and even
the smartest of programmers can be strained beyond thought-retention capacity.
Limiting the number of things you must keep in your head helps to ensure that
each has meaning. Isn't the whole point of
object-oriented programming to think about objects instead of about functions?
Holding seven objects in your head gets you a lot further than holding seven
functions -- unless you're thinking about avoiding lots of problems and dark
corners, that is.
Scalability and Java
The illusion in C++ is that you get to think about nothing but objects. You do get to think about objects,
of course, but you also have to think about lots of other things. It's possible,
then, that a language like Java (you knew where I was going with this, didn't you?) scales better than C++, because
with Java you can think about objects a lot more than you can with C++. Java's
scalability lets me build a much bigger project faster. (Note that I said I could build the project faster, not that it would run
fast.)
I am starting to believe the execution speeds will get significantly faster, as well.
Download the current beta of JDK 1.3 from java.sun.com to see for
yourself. But more and more, when I build a C++ program or look at some difficult issue in C++, I'm very aware that doing it in Java is much easier. The simple fact that
in Java there's only one way to create objects (on the heap) and everything is garbage-collected (it's surprising what you can do when you don't have to worry about object
clean-up) makes a big difference. But when you add enforced exceptions, a singly-rooted hierarchy, built-in threading,
Swing, all the cross-platform issues, and
-- of course -- tons of libraries, Java makes a huge difference. I'm not saying
Java is perfect; I have seen many language and library designs that are anywhere from poor all the way to
shoddy. But Java is such an improvement that more and more companies can't afford not to look at
it. Language can easily make the difference between getting a project done on time and not getting it done at all.
|