
In Praise of C and C++
Date: Jul 19, 2002
Article is provided courtesy of Addison Wesley.
Introduction
While Java and C# have been receiving all of the publicity of late, a lot of software is still being written in C and C++. Indeed, many traditional languages such as COBOL, FORTRAN, and Ada are still in widespread use. Although I harbor a certain fondness for COBOL, and have written more Java code over the past five years than is probably good for me, I'm finding more and more that I'm drawn back to C and C++.
I'm coming back to C and C++ in part because I prefer stable development environments, and because I've come to appreciate the power of object-oriented scripting languages, particularly Ruby. Ruby is evolving rapidly, but then I don't try to write really long-lived code in a scripting language. I use scripting languages for code that I want to be able to write rapidly, to test ideas or to implement some valuable functionality quickly.
For applications that have to last a long time, I prefer to use C and C++. Java is kind of neat in some ways, but it has been a moving target. Just as you get an application working with one set of class libraries, the rest of the Java community adopts a different implementation as the "standard"at least for the next year or so. And to add to the fun, there are always the rumors about Java being radically changed by the addition of templates, something that would drastically alter the class libraries yet again.
Taking the Long View
I might be a heretic, but I'm coming to realize that while the bleeding edge of technology might be good for my résumé, for most business applications it's actually counterproductive. For the types of applications I've worked on over the yearsmanagement information systems, manufacturing systems, finance applications, middleware, and e-commerce appsbleeding edge is not important. What really matters is rock solid, maintainable software that can be used reliably 24 hours a day, 365 days a year.
Most of these applications required a large investment of time and money, with the intention that the new system would continue to evolve and improve for many years before needing replacement. With C and C++, it's easy to encapsulate dependencies on specific operating systems or components so that the application can be ported to new operating systems, databases, messaging subsystems, or GUI libraries. True, the port can sometimes be quite expensive, but it's always cheaper than rewriting the entire application, which would happen when the formerly bleeding-edge Java application is completely rewritten in C# to exploit some new GUI widget that's available only on the .NET platform.
But What About Productivity?
Over the years there have been many different "rapid application development" tools and technologies, and they've been more productive environments than C and C++. Smalltalk, Java, and even Visual Basic are all good examples of productive application development environments. Unfortunately, they're also good examples of environments that, for one reason or another, haven't enabled developers to create long-lived applications.
Until these "productive" development environments mature to the point at which companies can trust them for long-lived, mission-critical applications, there will always be a role for C and C++. The reason is that for large applications, organizations don't want to face the hassle of rewriting an application every four or five years. After all, many organizations have mainframe applications that have lasted for 25 years or more, so why should they be forced to rewrite their new applications so soon?
Productivity Comes from Reuse
One difference in productivity among the various programming languages is the capabilities of the libraries that are part of the development environment. Developers are productive when using Java because of the size of the JDK class libraries. The same thing is true for Smalltalk and Visual Basic. It's not so much the language that's productiveit's all of the bundled libraries. Once developers have learned the libraries that come with a language, they can be extraordinarily productive compared with writing a traditional 3GL.
But guess what? Interesting though this comparison may be, it's misleading. Teams that use C and C++ have a massive range of code libraries available for them to use; they're just not always packaged as neatly as the JDK or the new .NET framework.
Teams that understand the benefits of reuse are productive in any language. They may start off a bit slower while the library of useful code is built up, but over time they stand to benefit from a deep knowledge of the internals of their libraries.
Leveraging Legacy Code
Another benefit of C and C++ is the ease with which they can interface to legacy code on practically any platform. This means that C and C++ applications can easily benefit from the reuse of legacy code, number-crunching routines written in FORTRAN, business logic and transactions in mainframe applications, and any code contained in platform-specific shared libraries.
This is in marked contrast to Java, where, although it's possible to make what are known as "native calls," very few development teams bother to do it. It's just so much easier for the team to rewrite everything in Java. So much for it being a productive environment.
Smalltalk and Visual Basic, on the other hand, suffer from the limitation of being available only on a limited set of platforms, so forget about invoking transactions on that RPG application running on an IBM AS/400. True, we could always use some messaging middleware such as MQ Series from our Visual Basic code to interact with the AS/400, but that just reemphasizes the value of C and C++. After all, most of the code examples for MQ Series are written in C.
Predictable Application Development
One of the really nice things about C and C++ is that they're predictable. It's easy to find out what the code is doing; you can step through the code in a debugger without having to worry what the runtime interpreter is doing "under the covers." This is why a lot of real-time and embedded code is still written in the more traditional languages such as C and Adabecause developers can predict how long routines will take to execute.
Most of the code libraries for C and C++ were written by developers who understand this need for predictability. Indeed, most libraries actually ship with the source code. This gives C and C++ developers many of the advantages of Open Source development, because many eyes have looked at the implementation of the libraries. This in turn makes development more predictable, because there are fewer hidden "gotchas" in the libraries, and it's rare for libraries to interact in unforeseen ways. This is in marked contrast to the Visual Basic world, where most of the reusable code is sealed away in precompiled DLLs. These DLLs often interact in unforeseen ways, so much so that the term DLL Hell has been used by many teams to describe the subtle interactions between the libraries.
Java treads the middle ground here, since the source for the standard JDK class libraries is available for any developer to read and review. On the other hand, many of the add-on class libraries for Java development environments don't come with source code. Java also has its own version of DLL Hellthe CLASSPATH. Getting the ordering on the CLASSPATH just right has hassled more than a few developers.
What About Memory Management?
The price of admission is that C developers (and, to a lesser extent, C++ developers) have to do some bookkeeping, but it's not that big a deal. It's not very hard to write C and C++ applications without memory leaks; all it takes is a little forethought. Obviously, the presence of destructors in C++ makes it much easier to manage memory in C++, but memory management is very easy to learn.
The Bottom Line
Having been drawn back to C and C++ by Ruby, I find it very interesting to notice that a lot of GNU and Open Source projects use C or C++ as their language of choice. (Indeed, Ruby itself is written in C, and hence can run on practically every platform that has a C compiler.) One of the first GNU projects was GCC, probably the most widely ported of the C and C++ compilers. (GCC now supports other languages than just C and C++.) C is also the systems programming language for most variants of the UNIX operating system.
What this means for developers is that the future of C and C++ is secure for a long time. Other languages might have nicer development environments and be marginally more productive, but for the core business logic of mission-critical applications I still prefer C and C++. I'd choose other languages for the rapidly evolving parts of the application such as the user interface and the web front-end, but for the core of the application I have nothing but praise for C and C++.