Copyright © Oct. 1996 Ian Joyner. All rights reserved.
[ To: next | prev | top | bottom ]
This is now the third edition of this critique; it has been four years since the last edition. The main factor to precipitate a new edition is that there are now more environments and languages available that rectify the problems of C++. The last edition was addressed to people who were considering adopting C++, in particular managers who would have to fund projects. There are now more choices, so comparison to the alternatives makes the critique less hypothetical.
The critique was not meant as an academic treatise, although some of the aspects relating to inheritance, etc., required a bit of technical knowledge. The critique is long; it would be good if it were shorter, but that would be possible only if there were less flaws in C++. Even so, the critique is not exhaustive of the flaws: I find new traps all the time. Instead of documenting every trap, the critique attempts to arrange the traps into categories and principles. This is because the traps are not just one off things, but more deeply rooted in the principles of C++. Neither is the critique a repository of `guess what this obscure code does' examples.
One desired outcome of this critique is that it should awaken the industry about the C++ myth and the fact that there are now viable alternatives to C++ that do not suffer from as many technical problems. The industry needs less hype and more sensible programming practices. No language can be perfect in every situation, and tradeoffs are sometimes necessary, but you can now feel free to choose a language which is more closely suited to your needs. The alternatives to C++ provide no silver bullet, but significantly reduce the risks and costs of software development compared to C++. The alternatives do not suffer under the complexities of C++ and do not burden the programmer with many trivialities which the compiler should handle; and they avoid many of the flaws and inanities of C/C++.
The language events which have made an update desirable are the introduction of Java, the wider availability of more stable versions of Eiffel, and the finalisation of the Ada 95 standard. Java in particular set out to correct the flaws of C++, and most sections in the original critique now make some comment on how Java addresses the problems. Eiffel never did have the same flaws as C++, and has been around since long before the original critique. Eiffel was designed to be object-oriented from the ground up, rather than a bolt-on. Java offers better integration with OO than C++. Now that there are language comparisons in the critique the arguments are less hypothetical, and the criticisms of C++ are more concrete.
Another factor has been the publishing of Bjarne Stroustrup's "Design and Evolution of C++" [Stroustrup 94]. This has many explanations of the problems of extending C with object-oriented extensions while retaining compatibility with C. In many ways, Stroustrup reinforces comments that I made in the original critique, but I differ from Stroustrup in that I do not view the flaws of C++ as acceptable, even if they are widely known, and many programmers know how to avoid the traps. Programming is a complex endeavour: complex and flawed languages do not help.
A question which has been on my mind in the last few years is when is OO applicable? OO is a universal paradigm. It is very general and powerful. There is nothing that you could not program in it. But is this always appropriate? Lower level programmers have tended to keep writing such things as device drivers in C. It is not lower levels that I am interested in, but the higher levels. OO might still be too low level for a number of applications. A recent book [Shaw 96] suggests that software engineers are too busy designing systems in terms of stacks, lists, queues, etc., instead of adopting higher level, domain-oriented architectures. [Shaw 96] offers some hope to the industry that we are learning how to architect to solve problems, rather than distorting problems to fit particular technologies and solutions.
For instance, commercial and business programming might be faster using a paradigm involving business objects. While these could be provided in an OO framework, the generality is not needed in commercial processing, and will slow and limit the flexibility of the development process. By analogy, walking is a fine mode of transport, but do I choose to walk everywhere? There seems to be a potentially large market for specialised paradigms, which support rapid application development (RAD) techniques. These paradigms may be based on some OO language, framework and libraries in the background. In anything though, we should be cautious, as this is an industry particularly prone to buzzwords and fads.
The second edition generated a lot of interest, and it was published in a number of places: Software Design in Japan translated it into Japanese, and published it over a series of months in 1993; it was published in an abridged form in TOOLS Pacific 1992; it was also published in Gregory's A Series Technical Journal. However, I resisted handing over copyright to anyone, as I wanted the paper to be freely available on the Internet; it is now available on more sites than I know about. My thanks to all those who have been so supportive of the 2nd edition.
Another reason for the 3rd edition is that the original critique was very much a product of newsgroup discussions. In this edition, I have attempted to at least improve the readability and flow, while not changing the overall structure or embarking on a complete rewrite. The primary goal has been to annotate the original with comparisons to Java and Eiffel.
C++ has become even more widely used over the last few years. However, people are starting to realise that it is not the answer to all programming problems, or that retaining compatibility with C is a good thing. In some sectors there has been a backlash, precipitated by the fact that people have found the production of defect free quality software an extremely difficult and costly task. OO has been over-hyped, but neither are its real benefits present in C++.
It is important and timely to question C++'s success. Several books are already published on the subject [Sakkinen 92], [Yoshida 92], and [Wiener 95]. A paper on the recommended practices for use in C++ [Ellemtel 92] suggests
"C++ is a difficult language in which there may be a very fine line between a feature and a bug. This places a large responsibility upon the programmer."Is this a responsibility or a burden? The `fine line' is a result of an unnecessarily complicated language definition. The C++ standardisation committee warns
"C++ is already too large and complicated for our taste" [X3J16 92].Sun's Java White Paper [Sun 95] says that in designing Java,
"The first step was to `eliminate redundancy' from C and C++. In many ways, the C language evolved into a collection of overlapping features, providing too many ways to do the same thing, while in many cases not providing needed features. C++, even in an attempt to add "classes in C" merely added more redundancy while retaining the inherent problems of C."The designer of Eiffel, Bertrand Meyer, states in the appendix "On language design and evolution" in [Meyer 92] some guiding principles of language design: simplicity vs complexity, uniqueness, consistency. "The Principle of Uniqueness," Meyer says,
"is easily expressed: the language should provide one good way to express every operation of interest; it should avoid providing two."Meyer has produced a seminal work on OO: Object-oriented Software Construction, [Meyer 88]. All software engineers and object-oriented practitioners should read and absorb this work. A completely revised 2nd edition is soon to appear. A later short book "Object Success" is directed to managers (probably the reason for the pun in the name), with an overview of OO, [Meyer 95].
While C programmers can immediately use C++ to write and compile C programs, this does not take advantage of OO. Many see this as a strength, but it is often stated that the C base is C++'s greatest weakness. However, C++ adds its own layers of complexity, like its handling of multiple inheritance, overloading, and others. I am not so sure that C is C++'s greatest weakness. Java has shown that in removing C constructs that do not fit with object-oriented concepts, that C can provide an acceptable, albeit not perfect base.
Adoption of C++ does not suddenly transform C programmers into object-oriented programmers. A complete change of thinking is required, and C++ actually makes this difficult. A critique of C++ cannot be separated from criticism of the C base language, as it is essential for the C++ programmer to be fluent in C. Many of C's problems affect the way that object-orientation is implemented and used in C++. This critique is not exhaustive of the weaknesses of C++, but it illustrates the practical consequences of these weaknesses with respect to the timely and economic production of quality software.
This paper is structured as follows: section 2 considers the role of a programming language; section 3 examines some specific aspects of C++; section 4 looks specifically at C; and the conclusion examines where C++ has left us, and considers the future. I have tried to keep the sections reasonably self contained, so that you can read the sections that interest you, and use the critique in a reference style. There are some threads that occur throughout the critique, and you will find some repetition of ideas to achieve self contained sections.
Having said that, I hope that you find this critique useful, and enjoyable: so please feel free to distribute it to your management, peers and friends.
[ To: next | prev | top | bottom ]
Comments to author: i.joyner@acm.orgAll contents copyright (C) 1996, Ian Joyner. All rights reserved.
Updated: 01 Jan 2000; Moved: Nov 16, 1997