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'.