GNU C++ Renovation Project

Edited March, 1994 by Roland Pesch (pesch@cygnus.com) Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.

Introduction

As you may remember, GNU C++ was the first native-code C++ compiler available under Unix (December 1987). In November 1988, it was judged superior to the AT&T compiler in a Unix World review. In 1990 it won a Sun Observer "Best-Of" award. But now, with new requirements coming out of the ANSI C++ committee and a growing backlog of bugs, it's clear that GNU C++ needs an overhaul.

The C++ language has been under development since 1982. It has evolved significantly since its original incarnation (C with Classes), addressing many commercial needs and incorporating many lessons learned as more and more people started using "object-oriented" programming techniques. In 1989, the first X3J16 committee meeting was held in Washington DC; in the interest of users, C++ was going to be standardized.

As C++ has become more popular, more demands have been placed on its compilers. Some compilers are up to the demands, others are not. GNU C++ was used to prototype several features which have since been incorporated into the standard, most notably exception handling. While GNU C++ has been an excellent experimental vehicle, it did not have the resources that AT&T, Borland, or Microsoft have at their disposal.

We believe that GNU C++ is an important compiler, providing users with many of the features that have made GNU C so popular: fast compilation, good error messages, innovative features, and full sources that may be freely redistributed. The purpose of this overhaul, dubbed the GNU C++ Renovation Project, is to take advantage of the functionality that GNU C++ offers today, to strengthen its base technology, and put it in a position to remain--as other GNU software currently is--the technical leader in the field.

This release represents the latest phase of work in strengthening the compiler on a variety of points. It includes many months of work concentrated on fixing many of the more egregious bugs that presented themselves in the compiler recently. In the coming months, we hope to continue expanding and enhancing the quality and dependability of the industry's only freely redistributable C++ compiler.

Changes in Behavior in GNU C++

The GNU C++ compiler continues to improve and change. A major goal of our work has been to continue to bring the compiler into compliance with the draft ANSI C++ standard, and with The Annotated C++ Reference Manual (the ARM). This section outlines most of the user-noticeable changes that might be encountered during the normal course of use.

Summary of Changes in Phase 1.3

The bulk of this note discusses the cumulative effects of the GNU C++ Renovation Project to date. The work during its most recent phase (1.3) had these major effects:

Much of the work in Phase 1.3 went to elimination of known bugs, as well as the major items above.

During the span of Phase 1.3, there were also two changes associated with the compiler that, while not specifically part of the C++ Renovation project, may be of interest:

Major Changes

This release includes four wholesale rewrites of certain areas of compiler functionality:

  1. Argument matching. GNU C++ is more compliant with the rules described in Chapter 13, "Overloading", of the ARM. This behavior is the default, though you can specify it explicitly with `-fansi-overloading'. For compatibility with earlier releases of GNU C++, specify `-fno-ansi-overloading'; this makes the compiler behave as it used to with respect to argument matching and name overloading.
  2. Default constructors/destructors. Section 12.8 of the ARM, "Copying Class Objects", and Section 12.1, "Constructors", state that a compiler must declare such default functions if the user does not specify them. GNU C++ now declares, and generates when necessary, the defaults for constructors and destructors you might omit. In particular, assignment operators (`operator =') behave the same way whether you define them, or whether the compiler generates them by default; taking the address of the default `operator =' is now guaranteed to work. Default copy constructors (`X::X(X&)') now function correctly, rather than calling the copy assignment operator for the base class. Finally, constructors (`X::X()'), as well as assignment operators and copy constructors, are now available whenever they are required.
  3. Binary incompatibility. There are no new binary incompatibilities in Phase 1.3, but Phase 1.2 introduced two binary incompatibilities with earlier releases. First, the functionality of `operator new' and `operator delete' changed. Name encoding ("mangling") of virtual table names changed as well. Libraries built with versions of the compiler earlier than Phase 1.2 must be compiled with the new compiler. (This includes the Cygnus Q2 progressive release and the FSF 2.4.5 release.)
  4. New g++ driver. A new binary g++ compiler driver replaces the shell script. The new driver executes faster.

New features

Enhancements and bug fixes

Problems with debugging

Two problems remain with regard to debugging:

Plans for Reno-2

The overall goal for the second phase of the GNU C++ Renovation Project is to bring GNU C++ to a new level of reliability, quality, and competitiveness. As particular elements of this strategy, we intend to:

  1. Fully implement ANSI exception handling.
  2. With the exception handling, add Runtime Type Identification (RTTI), if the ANSI committee adopts it into the standard.
  3. Bring the compiler into closer compliance with the ARM and the draft ANSI standard, and document what points in the ARM we do not yet comply, or agree, with.
  4. Add further support for the DWARF debugging format.
  5. Finish the work to make the compiler compliant with ARM Section 12.6.2, initializing base classes in declaration order, rather than in the order that you specify them in a mem-initializer list.
  6. Perform a full coverage analysis on the compiler, and weed out unused code, for a gain in performance and a reduction in the size of the compiler.
  7. Further improve the multiple inheritance implementation in the compiler to make it cleaner and more complete.

As always, we encourage you to make suggestions and ask questions about GNU C++ as a whole, so we can be sure that the end of this project will bring a compiler that everyone will find essential for C++ and will meet the needs of the world's C++ community.

The Template Implementation

The C++ template(1) facility, which effectively allows use of variables for types in declarations, is one of the newest features of the language.

GNU C++ is one of the first compilers to implement many of the template facilities currently defined by the ANSI committee.

Nevertheless, the template implementation is not yet complete. This chapter maps the current limitations of the GNU C++ template implementation.

Limitations for function and class templates

These limitations apply to any use of templates (function templates or class templates) with GNU C++:

Template definitions must be visible
When you compile code with templates, the template definitions must come first (before the compiler needs to expand them), and template definitions you use must be visible in the current scope.
Individual initializers needed for static data
Templates for static data in template classes do not work. See section Limitations for class templates.

Limitations for function templates

Function templates are implemented for the most part. The compiler can correctly determine template parameter values, and will delay instantiation of a function that uses templates until the requisite type information is available.

The following limitations remain:

Limitations for class templates

Debugging information for templates

Debugging information for templates works for some object code formats, but not others. It works for stabs(2) (used primarily in A.OUT object code, but also in the Solaris 2 version of ELF), and the MIPS version of COFF debugging format.

DWARF support is currently minimal, and requires further development.

GNU C++ Conformance to ANSI C++

These changes in the GNU C++ compiler were made to comply more closely with the ANSI base document, The Annotated C++ Reference Manual (the ARM). Further reducing the divergences from ANSI C++ is a continued goal of the GNU C++ Renovation Project.

Section 3.4, Start and Termination. It is now illegal to take the address of the function `main()'.

Section 4.8, Pointers to Members. The compiler produces an error for trying to convert between a pointer to a member and the type `void *'.

Section 5.2.5, Increment and Decrement. It is an error to use the increment and decrement operators on an enumerated type.

Section 5.3.2, Sizeof. Doing sizeof on a function is now an error.

Section 5.3.4, Delete. The syntax of a cast-expression is now more strictly controlled.

Section 7.1.1, Storage Class Specifiers. Using the static and extern specifiers can now only be applied to names of objects, functions, and anonymous unions.

Section 7.1.1, Storage Class Specifiers. The compiler no longer complains about taking the address of a variable which has been declared to have register storage.

Section 7.1.2, Function Specifiers. The compiler produces an error when the inline or virtual specifiers are used on anything other than a function.

Section 8.3, Function Definitions. It is now an error to shadow a parameter name with a local variable; in the past, the compiler only gave a warning in such a situation.

Section 8.4.1, Aggregates. The rules concerning declaration of an aggregate are now all checked in the GNU C++ compiler; they include having no private or protected members and no base classes.

Section 8.4.3, References. Declaring an array of references is now forbidden. Initializing a reference with an initializer list is also considered an error.

Section 9.5, Unions. Global anonymous unions must be declared static.

Section 11.4, Friends. Declaring a member to be a friend of a type that has not yet been defined is an error.

Section 12.1, Constructors. The compiler generates a default copy constructor for a class if no constructor has been declared.

Section 12.6.2, Special Member Functions. When using a mem-initializer list, the compiler will now initialize class members in declaration order, not in the order in which you specify them. Also, the compiler enforces the rule that non-static const and reference members must be initialized with a mem-initializer list when their class does not have a constructor.

Section 12.8, Copying Class Objects. The compiler generates default copy constructors correctly, and supplies default assignment operators compatible with user-defined ones.

Section 13.4, Overloaded Operators. An overloaded operator may no longer have default arguments.

Section 13.4.4, Function Call. An overloaded `operator ()' must be a non-static member function.

Section 13.4.5, Subscripting. An overloaded `operator []' must be a non-static member function.

Section 13.4.6, Class Member Access. An overloaded `operator ->' must be a non-static member function.

Section 13.4.7, Increment and Decrement. The compiler will now make sure a postfix `operator ++' or `operator --' has an int as its second argument.

Name Encoding in GNU C++

In order to support its strong typing rules and the ability to provide function overloading, the C++ programming language encodes information about functions and objects, so that conflicts across object files can be detected during linking. (3) These rules tend to be unique to each individual implementation of C++.

The scheme detailed in the commentary for 7.2.1 of The Annotated Reference Manual offers a description of a possible implementation which happens to closely resemble the cfront compiler. The design used in GNU C++ differs from this model in a number of ways: