Go forward to Enhancements and bug fixes.
Go backward to Major changes.
Go up to Changes.

New features
============

   * The compiler warns when a class contains only private constructors
     or destructors, and has no friends.  At the request of some of our
     customers, we have added a new option, `-Wctor-dtor-privacy' (on by
     default), and its negation, `-Wno-ctor-dtor-privacy', to control
     the emission of this warning.  If, for example, you are working
     towards making your code compile warning-free, you can use
     `-Wall -Wno-ctor-dtor-privacy' to find the most common warnings.

   * There is now a mechanism which controls exactly when templates are
     expanded, so that you can reduce memory usage and program size and
     also instantiate them exactly once.  You can control this
     mechanism with the option `-fexternal-templates' and its
     corresponding negation `-fno-external-templates'.  Without this
     feature, space consumed by template instantiations can grow
     unacceptably in large-scale projects with many different source
     files.  The default is `-fno-external-templates'.

     You do not need to use the `-fexternal-templates' option when
     compiling a file that does not define and instantiate templates
     used in other files, even if those files *are* compiled with
     `-fexternal-templates'.  The only side effect is an increase in
     object size for each file that was compiled without
     `-fexternal-templates'.

     When your code is compiled with `-fexternal-templates', all
     template instantiations are external; this requires that the
     templates be under the control of `#pragma interface' and `#pragma
     implementation'.  All instantiations that will be needed should be
     in the implementation file; you can do this with a `typedef' that
     references the instantiation needed.  Conversely, when you compile
     using the option `-fno-external-templates', all template
     instantiations are explicitly internal.

     `-fexternal-templates' also allows you to finally separate class
     template function definitions from their declarations, thus
     speeding up compilation times for every file that includes the
     template declaration.  Now you can have tens or even hundreds of
     lines in template declarations, and thousands or tens of thousands
     of lines in template definitions, with the definitions only going
     through the compiler once instead of once for each source file.
     It is important to note that you must remember to externally
     instantiate *all* templates that are used from template
     declarations in interface files.  If you forget to do this,
     unresolved externals will occur.

     In the example below, the object file generated (`example.o') will
     contain the global instantiation for `Stack<int>'.  If other types
     of `Stack' are needed, they can be added to `example.cc' or placed
     in a new file, in the same spirit as `example.cc'.

     `foo.h':
          #pragma interface "foo.h"
          template<class T>
          class Stack {
            static int statc;
            static T statc2;
            Stack() { }
            virtual ~Stack() { }
            int bar();
          };

     `example.cc':
          #pragma implementation "foo.h"
          #include "foo.h"
          
          typedef Stack<int> t;
          int Stack<int>::statc;
          int Stack<int>::statc2;
          int Stack<int>::bar() { }

     Note that using `-fexternal-templates' does not reduce memory usage
     from completely different instantiations (`Stack<Name>' vs.
     `Stack<Net_Connection>'), but only collapses different occurrences
     of `Stack<Name>' so that only one `Stack<Name>' is generated.

     `-falt-external-templates' selects a slight variation in the
     semantics described above (incidentally, you need not specify both
     options; `-falt-external-templates' implies
     `-fexternal-templates').

     With `-fexternal-templates', the compiler emits a definition in the
     implementation file that includes the header definition, *even if*
     instantiation is triggered from a *different* implementation file
     (e.g. with a template that uses another template).

     With `-falt-external-templates', the definition always goes in the
     implementation file that triggers instantiation.

     For instance, with these two header files--

     `a.h':
          #pragma interface
          template <class T> class A { ... };
     `b.h':
          #pragma interface
          class B { ... };
          void f (A<B>);

     Under `-fexternal-templates', the definition of `A<B>' ends up in
     the implementation file that includes `a.h'.  Under
     `-falt-external-templates', the same definition ends up in the
     implementation file that includes `b.h'.

   * You can control explicitly where a template is instantiated,
     without having to *use* the template to get an instantiation.

     To instantiate a class template explicitly, write `template class
     NAME<paramvals>', where PARAMVALS is a list of values for the
     template parameters.  For example, you might write

          template class A<int>

     Similarly, to instantiate a function template explicitly, write
     `template FNSIGN' where FNSIGN is the particular function
     signature you need.  For example, you might write

          template void foo (int, int)

     This syntax for explicit template instantiation agrees with recent
     extensions to the draft ANSI standard.

   * The compiler's actions on ANSI-related warnings and errors have
     been further enhanced.  The `-pedantic-errors' option produces
     error messages in a number of new situations: using `return' in a
     non-`void' function (one returning a value); declaring a local
     variable that shadows a parameter (e.g., the function takes an
     argument `a', and has a local variable `a'); and use of the `asm'
     keyword.  Finally, the compiler by default now issues a warning
     when converting from an `int' to an enumerated type.  This is
     likely to cause many new warnings in code that hadn't triggered
     them before.  For example, when you compile this code,

          enum boolean { false, true };
          void
          f ()
          {
            boolean x;
          
            x = 1; //assigning an `int' to an `enum' now triggers a warning
          }

     you should see the warning "`anachronistic conversion from integer
     type to enumeral type `boolean''".  Instead of assigning the value
     1, assign the original enumerated value `true'.