9. Looking Ahead

You cannot bathe in the same river twice.

Heraclitus

Did C++ succeed at what it was designed for? — is C++ a coherent language? — what should have been different? — what should have been added? — what was the biggest mistake? — is C++ only a bridge? — what is C++ good for? — what will make C++ much more effective?

9.1 Introduction

This chapter is more speculative and relies more on personal opinions and generalizations than I like; I much prefer to present completed work and experience. However, this chapter answers common questions and presents issues that invariably come up when the design of C++ is discussed. The chapter consists of three related parts:

– A retrospective trying to assess where C++ currently is relative to its aims and relative to where it might have been (§9.2).

– A look at probable future problems for software development and programming languages to see how C++ might address them and fit into a changed world (§9.3).

– A look at some areas where C++ and its use can be significantly improved to make C++ a better tool (§9.4).

Discussing future developments is always hazardous, but it is a necessary hazard: Language design must in part anticipate future problems.

9.2 Retrospective

It is often claimed that hindsight is an exact science. It is not. The claim is based on the false assumptions that we know all relevant facts about the past, that we know the current state of affairs, and that we have a suitably detached point of view from which to judge. Typically, none of these conditions hold. Thus, a retrospective on something as large, complex, and dynamic as a programming language in large-scale use is not just a statement of fact. Anyway, let me try to stand back and answer some hard questions:

[1] Did C++ succeed at what it was designed for?

[2] Is C++ a coherent language?

[3] What was the biggest mistake?

Naturally, the replies to these questions are related. My basic answers are “yes,” “yes,” and “not shipping a larger library with Release 1.0.”

9.2.1 Did C++ succeed at what it was designed for?

“C++ is a general-purpose programming language designed to make programming more enjoyable for the serious programmer” [Stroustrup, 1986b]. In this goal, C++ clearly succeeded. More specifically, it succeeded by enabling reasonably educated and experienced programmers to write programs at a higher level of abstraction (“just like in Simula”) without loss of efficiency compared to C. It allowed this for applications that were simultaneously demanding in time, space, inherent complexity, and constraints from the execution environment.

More generally, C++ made object-oriented programming and data abstraction available to the community of software developers that until then had considered such techniques and the languages that supported them such as Smalltalk, Clu, Simula, Ada, 00 Lisp dialects, etc., with disdain and even scorn: “expensive toys unfit for real problems.” C++ did three things to overcome this formidable barrier:

[1] C++ produced code with run-time and space characteristics that competed head-on with the perceived leader in that field: C. Anything that matches or beats C must be fast enough. Anything that doesn’t, can and will – out of necessity or mere prejudice – be ignored. It produced such performance from code relying on data abstraction and object-oriented techniques as well as for traditionally organized code.

[2] C++ allowed such code to be integrated into conventional systems and to be produced on traditional systems. A conventional degree of portability was essential. So was the ability to coexist with existing code and with traditional tools, such as debuggers and editors.

[3] C++ allowed a gradual transition to these new programming techniques. It takes time to learn new techniques. Companies simply cannot afford to have significant numbers of programmers unproductive while they are learning. Nor can they afford projects that fail because programmers overenthusiastically misapply partially-mastered new ideas.

C++ made object-oriented programming and data abstraction cheap and accessible.

In succeeding, C++ didn’t just help its own user community. It also provided a major impetus to languages that support different aspects of object-oriented programming and data abstraction. C++ isn’t everything to all people and doesn’t deliver on every promise ever made about some language or other. It wasn’t meant to, and I didn’t make extravagant promises. However, C++ did deliver on its own promises often enough to break down the wall of disbelief that stood in the way of all languages that allowed programmers to work at a higher level of abstraction. By doing so, C++ opened many doors for itself and also for languages whose supporters tend to see C++ as a competitor only. In addition, C++ helped users of other languages by providing a strong incentive to implementers to improve the performance and flexibility of those languages.

9.2.2 Is C++ a Coherent Language?

Basically, I am happy with the language, and quite a few users agree. There are many details I’d like to improve if I could. However, the fundamental concept of a statically-typed language relying on classes with virtual functions and providing facilities for low-level programming is sound. Also, the major features work together in a mutually supportive fashion.

9.2.2.1 What Should and Could Have Been Different?

What would be a better language than C++ for the things C++ is meant for? Consider the first-order decisions (§1.1, §2.3, §2.7):

– Use of static type checking and Simula-like classes.

– Clean separation between language and environment.

– C source compatibility (“as close as possible”).

– C link and layout compatibility (“genuine local variables”).

– No reliance on garbage collection.

I still consider static type checking essential for good design and run-time efficiency. Were I to design a new language for the kind of work done in C++ today, I would again follow the Simula model of type checking and inheritance, not the Smalltalk or Lisp models. As I have said many times, “Had I wanted an imitation Smalltalk, I would have built a much better imitation. Smalltalk is the best Smalltalk around. If you want Smalltalk, use it” [Stroustrup,1990]. Having both static type checking and dynamic type identification (for example, in the form of virtual function calls) implies some difficult tradeoffs compared to languages with only static or only dynamic type checking. The static and dynamic type models cannot be identical, and there will therefore be some complexity and inelegance that could be avoided by supporting only one type model. However, I wouldn’t want to write programs with only one model.

I also still consider a separation between the environment and the language essential. I do not want to use only one language, one set of tools, and one operating system. To offer a choice, separation is necessary. However, once the separation exists, one can provide different environments to suit different tastes and different requirements for supportiveness, resource consumption, and portability.

We never have a clean slate. It is not enough to provide something new; we must also make it possible for people to make a transition from old tools and ideas to new. Thus, if C hadn’t been there for C++ to be almost compatible with, I would have chosen to be almost compatible with some other language. However, any compatibility requirements imply some ugliness. By building on C, C++ inherited some syntactic oddities, some rather messy conversion rules for built-in types, etc. These imperfections have been a continuing hassle, but the alternatives – significant incompatibilities with C in a C-based language or getting a language built completely from scratch into widespread use – would have been much more troublesome. In particular, the link and library compatibility with C has been essential. Link compatibility with C implies that C++ can link with most other languages because they provide a binding to code written in C.

Should a language have reference semantics for variables (that is, a name is really a pointer to an object allocated elsewhere), such as in Smalltalk or Modula-3, or true local variables, such as in C and Pascal? This question is critical. It relates to several issues such as coexistence with other languages, run-time efficiency, memory management, and the use of polymorphic types. Simula dodged the question by having references to class objects (only) and true local variables for objects of built-in types (only). I consider it an open issue whether a language can be designed that provides the benefits of both references and true local variables without ugliness. Given a choice between elegance and the benefits of having both references and true local variables, I’ll take the two kinds of variables.

Should a new language support garbage collection directly, say, as Modula-3 does? If so, could C++ have met its goals had it provided garbage collection? Garbage collection is great when you can afford it. Therefore, the option of having garbage collection is clearly desirable. However, garbage collection can be costly in terms of run time, real-time response, and porting effort (exactly how costly is the topic of much confused debate). Therefore, being forced to pay for garbage collection at all times isn’t a blessing. C++ allows optional garbage collection [2nd,pp466-468]. Several experiments with garbage-collecting C++ implementations are in progress. I expect to rely on garbage collection in some, but not all, of my C++ programs within a couple of years (§10.7). However, I am convinced (after reviewing the issue many times over the years) that had C++ depended on garbage collection, it would have been stillborn.

9.2.2.2 What Should Have Been Left Out?

Even [Stroustrup,1980] voiced concern that C with Classes might have become too large. I think “a smaller language” is number one on any wish list for C++, yet people deluge me and the standards committee with extension proposals. I see no major part of C++ that could be removed without leaving important techniques unsupported. Even if we could completely disregard compatibility issues, only a few simplifications of C++’s fundamental mechanisms would be possible. These would primarily be in the C subset of C++ – sometimes we forget that C itself is a rather large and complicated language.

The fundamental reason for the size of C++ is that it supports more than one way of writing programs, more than one programming paradigm. From one point of view, C++ is really three languages in one:

– A C-like language (supporting low-level programming)

– An Ada-like language (supporting abstract data type techniques)

– A Simula-like language (supporting object-oriented programming)

– What it takes to integrate those features into a coherent whole.

One can write programs in those styles in a language like C also, but C provides no direct support for data abstraction or object-oriented programming. C++, on the other hand, supports several alternatives directly.

There always is a design choice but in most languages the language designer has made the choice for you. For C++ I did not; the choice is yours. This flexibility is naturally distasteful to people who believe that there is exactly one right way of doing things. It can also scare beginners and teachers who feel that a good language is one that you can completely understand in a week. C++ is not such a language. It was designed to provide a toolset for professionals, and complaining that there are too many features is like the “layman” looking into an upholsterer’s tool chest and exclaiming that there couldn’t possibly be a need for all those little hammers.

Every language in nontrivial use grows to meet the needs of its user community. This invariably implies an increase of complexity. C++ is part of a trend towards greater language complexity to deal with the even greater complexity of the programming tasks attempted. If the complexity doesn’t appear in the language itself, it appears in libraries or tools. Examples of languages/systems that have grown enormously compared to their simpler origins are Ada, Eiffel, Lisp (CLOS), and Smalltalk. Because of C++’s emphasis on static type checking, much of the increase in complexity has appeared in the form of language extensions.

C++ was designed for serious programmers and grew to serve them in the increasing large and complex tasks they face. The result can be overwhelming for newcomers, even experienced newcomers. I have tried to minimize the practical effects of C++’s size by making it possible to learn and use C++ in stages (§7.2). The traditional negative performance impact of a large language has also been minimized by avoiding “distributed fat” (§4.5).

9.2.2.3 What Should Have Been Added?

As ever, the principle is to add as little as possible. A letter published on behalf of the extensions working group of the C++ standards committee puts it this way [Stroustrup, 1992b]:

“First, let us try to dissuade you from proposing an extension to the C++ language. C++ is already too large and complicated for our taste and there are millions of lines of C++ code “out there” that we endeavor not to break. All changes to the language must undergo tremendous consideration. Additions to it are undertaken with great trepidation. Wherever possible we prefer to see programming techniques and library functions used as alternatives to language extensions.

Many communities of programmers want to see their favorite language construct or library class propagated into C++. Unfortunately, adding useful features from diverse communities could turn C++ into a set of incoherent features. C++ is not perfect, but adding features could easily make it worse instead of better.”

So, given that, what features have caused trouble by their absence and which are under debate so that they might make it into C++ over the next few years? Basically, the features described in this book (including the ones in Part II such as templates, exceptions, namespaces, and run-time type identification) are enough features for me. I’d like optional garbage collection too, but I classify that as a quality of implementation issue rather than a language feature.

9.2.3 What Was The Biggest Mistake?

To my mind, there really is only one contender for the title of Worst Mistake. Release 1.0 and my first edition [Stroustrup,1986] should have been delayed until a larger library including some fundamental classes such as singly and doubly linked lists, an associative array class, a range-checked array class, and a simple string class could have been included. The absence of those led to everybody reinventing the wheel and to an unnecessary diversity in the most fundamental classes. It also led to a serious diversion of effort. In an attempt to build such fundamental classes themselves, far too many new programmers started dabbling with the “advanced” features necessary to construct good foundation classes before they had mastered the basics of C++. Also, much effort went into techniques and tools to deal with libraries inherently flawed by the lack of template support.

Could I have avoided that? In a sense, I obviously could have. The original plan for my book included three library chapters, one on the stream library, one on the container classes, and one on the task library. I knew roughly what I wanted. Unfortunately, I was too tired and couldn’t do container classes without some form of templates. The idea of “faking” templates by a preprocessor or an incomplete compiler hack unfortunately didn’t occur to me.

9.3 Only a Bridge?

I built C++ as a bridge over which people could pass from traditional programming to styles relying on data abstraction and object-oriented programming. Does C++ have a future beyond that? Is C++ only a bridge? Once across to a world where data abstraction and object-oriented programming are second nature, are the features provided by C++ valuable by themselves or does its inheritance from C become a fatal liability? Also, assuming a positive answer, can anything be done for C++ users who don’t care about C compatibility without causing damage to the people who will continue to care for at least the next decade?

A language exists to help solve problems. If a language is initially successful, it will survive as long as people face the kinds of problems it helps them to solve. In addition, it ought to thrive provided no other language provides significantly better solutions for that set of problems. Thus, the questions become

– Will the problems C++ helps solve remain real?

– Will significantly better solutions emerge?

– Will C++ provide good solutions for new problems?

My basic answers are “many will,” “slowly,” and “yes.”

9.3.1 We Need the Bridge for a Long Time

It will take people a long time to reach the level of sophistication and maturity with object-oriented programming, object-oriented design, etc., that I envisioned. The migration to C++ will not be complete five years from now. C++’s role as a bridge and as a vehicle for hybrid design and development will outlast this century. Its role as a vehicle for maintenance and upgrading of old code will last longer still.

It is sobering to realize that in places the move from assembler to C isn’t yet complete. In the same way, the move from C to C++ may last for a long time. However, in this lies part of C++’s strength. To those who really need some pure C style, those styles are readily available and efficient in C++. Supporting those styles – both during a transition and where they simply are the most appropriate style – is part of C++’s fundamental aims.

9.3.2 If C++ is the Answer, What is the Question?

There is no one such question. C++ is a general-purpose language – or at least a multi-purpose one. This implies that for every single specific question, you can construct a language or system that is a better answer than C++. C++’s strength comes from being a good answer to many questions rather than being the best answer to one specific question. For example, like C, C++ is an excellent language for low-level systems work and typically outperforms any other high-level language for this kind of work. However, for most machine architectures, a good assembly programmer can produce code that is significantly smaller and faster than a good C++ compiler can. Usually, this is not significant because the fraction of a complete system where that difference is important is small, and the system would be unaffordable and unmaintainable if written completely in assembler.

I find it hard to imagine an application area for which one couldn’t construct a specialized language better than C++ – and better than any other general-purpose language. Thus, the most a general-purpose language can hope for is to be “everybody’s second choice.”

That said, I’ll examine some areas where C++ has fundamental strengths:

– Low-level systems programming

– Higher-level systems programming

– Embedded code

– Numeric/scientific computing

– General application programming

These categories are not distinct, nor do they have universally agreed-upon definitions. C++ will remain a good choice in all of these areas; further, any language that is a good choice will look a lot like C++ at the level of the fundamental services offered – though probably not at the syntactic or detailed semantic level. These areas don’t exhaust the kinds of applications in which C++ has been used with success, but they represent key problems that C++ must address to continue to prosper.

9.3.2.1 Low-level Systems Programming

C++ is the best language available for low-level programming. It combines C’s strengths in this area with the ability to do simple data abstraction at no cost in runtime and space and to manage larger programs of this sort. No new language is going to be sufficiently better in this area to replace C++. Systems programming involving a low-level component will remain an area of strength for C++. In this area, C++ fills its role as a better C. For years, the only real competitor to C++ in this area will remain C, and here C++ is the better choice exactly because it is a better C. I expect low-level systems programming to slowly – only slowly – decrease in importance and remain a significant area of strength for C++. For this reason, care must be taken not to “improve” the C++ language or C++ implementations to the point where it is only a higher-level language.

9.3.2.2 Higher-level Systems Programming

The size and complexity of traditional systems programs are growing rapidly. Examples are operating system kernels, network managers, compilers, email systems, typesetting programs, picture and sound manipulation systems, communication systems, user interfaces, and database systems. Consequently, the traditional emphasis on low-level efficiency gives way to a concern about overall structure. Efficiency still matters, but it becomes secondary in that it is irrelevant unless the larger systems can be economically constructed and maintained.

C++’s facilities for data abstraction and object-oriented programming directly address this concern. Templates, namespaces, and exceptions will become increasingly important to C++ programmers working on these kinds of applications. Isolating necessary violations of the type system in low-level functions, subsystems, and libraries will also become more critical. This technique keeps the main application code type safe and therefore easier to maintain. I expect higher-level systems programming to continue to grow in importance for many years and to be an area of strength for C++.

Many other languages can also serve higher-level systems programming well. Examples are Ada9X, Eiffel, and Modula-3. Except for support for garbage collection and concurrency, these languages are roughly equivalent to C++ in the fundamental mechanisms they offer. Naturally, the quality of individual features and their integration into a language can be discussed forever. Most programmers will have strong preferences. However, if implementations of sufficient quality become available, each of these languages can support a wide variety of systems applications. Problems unrelated to programming language-technical details, such as management, design techniques, and programmer education, will dominate development. C++ tends to have an advantage in run-time efficiency, flexibility, availability, and user community that gives it a competitive edge.

For some larger systems applications, garbage collection is a major advantage; for others, it is a hindrance. Unless C++ implementations provide optional garbage collection, C++ will suffer a systematic disadvantage in some areas, but I’m confident that C++ implementations supporting optional garbage collection will become common.

9.3.2.3 Embedded Systems

One area of systems programming that deserves special mention is embedded code; that is, programs running on computerized devices such as cameras, cars, rockets, and telephone switches. I expect this kind of work to increase in importance and to consist of a mixture of low-level and higher-level systems programming for which C++ is most suitable. Different applications and different organizations will create a variety of demands that a specialized language will be hard-pressed to meet. Some designs will rely heavily on exceptions; others will ban them as being too unpredictable. Similarly, the requirements for memory management will range from “no dynamic memory allowed” to “automatic garbage collection must be used.” In addition, a variety of different concurrency models will be used. It is important that C++ is a language rather than a complete system. This allows C++ to fit into specialized systems and to produce code for specialized execution environments. Being able to run C++ in separate development environments and in simulators on stock hardware can be essential for a project. The fact that C++ programs can be put into ROM has also been important in the past. I have high expectations for C++ in the area of programming computerized gadgets of all sorts. In this area, C++ can again build on C’s traditional strengths.

9.3.2.4 Numeric/Scientific Computing

Numeric/scientific computing is a relatively small area in terms of number of programmers, but it is a very interesting and important one. I see a drift towards advanced algorithms that favor languages capable of expressing a variety of data structures and using them efficiently. This increased emphasis on flexibility compensates for Fortran’s advantage in basic vector computation. Importantly, C++ programs can call basic Fortran and assembler routines where necessary or simply convenient. The integration of numeric programs into larger applications creates demands that suit C++. For example, Fortran’s advantages in low-level computation are minimized when the emphasis is on nonnumeric concerns such as visualization, simulation, database access, and real-time data gathering.

9.3.2.5 General Application Programming

C++ is not ideally suited for applications that do not have major systems-programming components and where the run-time and space efficiency requirements are not demanding. However, when supported by libraries and possibly by a garbage collector C++ often is a viable tool.

I expect specialized languages, program generators, and direct manipulation tools to dominate many such application areas. For example, why write program text to generate a user interface when you can have the code generated by a program given an example screen layout composed from a menu? Similarly, why write Fortran or C++ to do advanced math when you can use much higher-level specialized languages? In such cases, however, the higher-level language, tool, or generator needs to be implemented in some suitable language and will often need to generate code in some lower-level language to actually perform the actions. The requirements for an implementation language and a target language usually fit C++ very well so I predict a major role for C++ as the implementation language for higher-level languages and tools. These are other roles that C++ inherits from C. C++ details such as the ability to declare variables almost anywhere combine with major program organization features such as namespaces to make C++ even better suited as a target language than C.

Higher-level tools and languages tend to be specialized. Consequently, good ones provide facilities for users to extend and modify the default behavior by adding code written in a lower-level language. C++’s abstraction mechanisms can be used to smoothly fit C++ code into a framework provided by a higher-level tool.

9.3.2.6 Mixed Systems

C++’s most significant strength comes from its ability to function in systems and organizations that combine aspects of several of these kinds of applications. My conjecture is that most significant systems and organizations need such combinations. User interfaces often need graphics; specific applications often rely on specialized languages and program generators; simulators and analytical subsystems require computation; communications subsystems require extensive systems programming; most large systems rely on some database; special hardware requires low-level work. In all these areas – and others – C++ will be at least the second choice. Overall, it will be the first choice often enough to be considered a major language.

All languages die or mutate to meet new challenges. A language with a large and vigorous user community will mutate rather than die. This is what happened to C yielding C++ and that is what some day will happen to C++. C++ is a relatively young language, but it is worthwhile considering its strengths and weaknesses to build on the former and compensate for the latter.

C++ isn’t perfect; it wasn’t designed to be and neither is any other general-purpose language. However, C++ is good enough not to be replaced by a similar language. Only a fundamentally different language could provide significant enough benefits to make it clearly superior. Just being a better C++ will not be sufficient to cause a change. That is why C++ isn’t just a better C: Had C++ not provided significant new ways of writing programs it wouldn’t have been worthwhile for programmers to upgrade from C. That is why Pascal and Modula-2 failed as alternatives to C even though a solid section of the academic community was pushing these languages for years: they were not sufficiently different from C to be significantly better. Also, if something better but not radically different appears, a lively and diverse community will simply absorb the new ideas and features. The initial design of C++ and its evolution into the current language provides ample examples of this.

I don’t see a fundamentally different language that in the near future could replace C++ across its application areas – just languages that provide essentially similar feature sets in different ways, niche languages, and experimental languages. I expect that some of these experimental languages will in time grow to provide significant improvements over what C++ is now and will evolve into over the next few years.

9.4 What Will Make C++ Much More Effective?

There is no room for complacency in the world of software development. Over the years, the growth of expectations has consistently outstripped even the fantastic improvements of both hardware and software, and I see no reason for this to change soon. Much can be done to make C++ implementations more helpful to their users, and much can be learned by programmers and designers to make themselves more effective. Here, I will hazard a few comments about what I think should be done to make C++ programming more effective.

9.4.1 Stability and Standards

Stability of the language definition and of key libraries and interfaces comes high on the list of requirements for further progress. The ANSI/ISO C++ standard should provide the former, and various organizations and companies are working on the latter in areas such as operating system interfaces, dynamically linked libraries, database interfaces, etc. I am looking forward to the day – not too far in the future – when C++ as described in this book is generally available on all major platforms. This will be of great help to the libraries and tools industry.

People will of course keep asking for new features, but I can live with C++ as described here. I conjecture that so can most programmers of production code. It is worth remembering that no single feature is essential for producing good code – for any definition of “good.”

9.4.2 Education and Technique

Of all the areas of C++ and its use, I see the greatest potential for improvement from simply learning new design and programming techniques. In principle, the easiest and cheapest improvements can be had by using C++ more effectively. No expensive tools are necessary. On the other hand, changing habits of thinking isn’t easy. For most programmers, what is needed is not simply training in a new syntax, but an education in new concepts. Have a look at §7.2 and read a textbook that touches upon design issues such as [2nd] or [Booch,1993]. I expect to see significant improvements in design and programming technique over the next few years, but that is no reason for delay. Most of us are far enough behind the current state of the art in one or more areas that we can reap significant benefits from some reading and experimentation right now. That’s also more fun than struggling at the bleeding edge of standards and tools.

9.4.3 Systems Issues

C++ is a language rather than a complete system. In most contexts that has been a strength, and tools are provided to make up a complete software development and execution environment. However, the interface between the language and the environment falls through the cracks of this classification. This has led to disappointingly slow progress in areas such as incremental linking and dynamic loading. By and large, people have done nothing, relied on mechanisms designed for C, or worked on mechanisms intended to be general enough to support “all object-oriented programming languages.” The results have been rather poor from the point of view of a C++ programmer.

Early experiments integrating C++ and dynamic linking were promising so I had expected dynamic linking of classes to be common years ago. For example, we had a technique for efficient and type-safe incremental linking based on abstract types running by 1990 [Stroustrup,1987d] [Dorward,1990]. The technique wasn’t much used in real systems, but abstract classes became important in maintaining firewalls, minimizing recompilation after change, and in general to ease the use of software components from multiple sources (§13.2.2).

Another important issue that languished because it didn’t fit well with the separation of the programmer’s world into distinct areas of concern was support for evolution of software. Fundamentally, the problem is that once a library is in use, you can change its implementation only if its users either don’t depend on implementation details such as the size of an object or are willing and able to recompile their code with the new version of the library. Object models such as Microsoft’s OLE2, IBM’s SOM, and the Object Management Group’s CORBA address this problem by providing an interface that hides implementation details and is supposedly language independent. The language independence imposes some awkwardness on the C++ programmer and typically some time or space overhead as well. In addition, each major section of the software industry seems to have its own “standard” for addressing this problem. Only time will tell to what extent these techniques help and hinder C++ programmers. The namespace mechanism provides an approach to interface evolution within the C++ language itself (§17.4.4).

I have reluctantly come to accept that some system-related issues would have been better handled within C++. System-related issues, such as dynamic linking of classes and interface evolution do not logically belong in a language and language-based solutions are not preferable on technical grounds. However, the language provides the only common forum in which a truly standard solution can become accepted. For example, the Fortran and C calling interfaces have become a de facto standard for inter-language calls. They are a standard because C and Fortran are popular and because their calling interfaces are simple and efficient – the lowest common denominator. I dislike this conclusion because it implies a barrier to the use of multiple languages in a system unless the mechanism supplied by a single language becomes accepted as a standard by other languages.

9.4.4 Beyond Files and Syntax

Let me outline the program development environment I’d like for C++. First of all, I want incremental compilation. When I make a minor change, I want “the system” to note that the change was minor and have the new version compiled and ready to run in a second. Similarly, I want simple requests, such as “Show me the declaration of this f?” “What fs are in scope here?” “What is the resolution of this use of +?” “Which classes are derived from class Shape?” and “What destructors are called at the end of this block?” answered in a second.

A C++ program contains a wealth of information that in a typical environment is available only to a compiler. I want that information at the programmer’s fingertips. However, most people look at a C++ program as a set of source files or as a string of characters. That is to confuse the representation with what is represented. A program is a collection of types, functions, statements, etc. To fit into traditional programming environments, these concepts are represented as characters in files.

Basing C++ implementations on character-oriented tools has been a major impediment to progress. If you have to preprocess and recompile every header file directly or indirectly included in the file containing a function in which you made a minor change, one-second recompilation is not going to happen. Several techniques exist for avoiding redundant recompilation, but dispensing with traditional source text and basing tools on an abstract internal representation seems to me the most promising and interesting approach. An early version of such a representation can be found in [Murray, 1992] [Koenig, 1992]. Naturally, we need text as input and for people to look at, but such text is easily absorbed into the system and easily reconstructed upon request. It need not be fundamental. Text in the C++ syntax formatted according to some indentation preference is just one of many alternative ways of looking at a program. The simplest application of this notion is to allow you to look at a program using your preferred layout style while I at the same time can look at the same program using my preferences.

A significant use of a non-textual representation would be as a target for code generation from higher-level languages, program generators, direct manipulation tools, etc. It would allow such tools to bypass the traditional C++ syntax. It might even become a tool for migrating C++ away from some of the more contorted aspects of its syntax. I maintain that C++’s type system and semantics are cleaner than its syntax. Within C++, there is a much smaller and cleaner language struggling to get out. An environment like the one I’m envisioning might be a way of proving that. Providing direct support for various forms for design are obvious applications.

From the notion of the syntax being the user interface of a language follows that alternative user interfaces are possible. The only really important constant in the system is the basic semantics of the language. That must be maintained at all times, and as long as that is the case, traditional C++ code in the familiar text form can always be produced on request.

An environment based on an abstract representation of C++ allows alternative ways of producing C++ and alternative ways of looking at C++. It would also provide alternative ways of linking, compiling, and executing code. For example, linking could be done before code generation because there would be no need to produce object code to gain access to linking information. The difference between an interpreter and a compiler would become somewhat academic because both would rely on the same information in roughly the same format.

9.4.5 Putting It All Together

C++’s main strength isn’t being great at a single thing, but being good at a great variety of things. Similarly, progress isn’t going to come primarily from a single improvement, but from a great variety of improvements in different areas. Better libraries, better design techniques, better-educated programmers and designers, a language standard, optional garbage collection, object-communication standards, databases, non-text-based environments, better tools, faster compilers, etc., will all contribute.

I think that we have barely begun to see what benefits we can reap from C++. The base has been constructed, but just the base. In the future, I expect to see the major activity and progress shift from the language proper – which is that base – to the tools, environments, libraries, applications, etc., that depend on it and build on it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset