Topic: Precompiling templates to highly decrease compile time and size of executables.


Author: Carlo <carlo@ims.gso.getronics.nl>
Date: 1996/07/25
Raw View
>>> [ I realize this is rather unusual long post, so I marked the important
>>>  parts with '>>>' ]

Hi,

when C++ was designed, it was a demand that it was backwards compatible
with C.  This gave rise to some rather "unlogical" parts of C++ concerning
OO, like the internal types not being classes. But for every 'problem' a
way to work around it has been made (eg. ostream::operator<<(int) and
operator<<(ostream&, class foo&)).

To me it seems however that in the design of templates this historical
burden has not been taken into account.  There are a few rather essential
features missing which I could really use.  There is also a good logical
reason of why these features are needed and how the lack of them might relate
to the internal types.

To start with one of these things: it would really be logical if template
parameters could be restricted to base class types.

Assume we have a base class:

class B { /* ... */ };

>>> Then a template definition could be:

template < class B::T > // Just making up some syntax here, T should be 'a B'
                        // (either B, or derived from B).
class A {
  // ...
};

The advantage of this is not only to protect the programmer of using a wrong
type for T, it is mainly because of logic that this should be possible.

>>> A direct consequence would be that templates can almost always be
>>> precompiled and used in a shared library for dynamical linking,
instead of having to compile the template EVERY time again when you use a
library that uses this template. This both, speeds up the compile time
enormously (when using lots of templates) as well as decreases the size of
the executables.


Let me now explain why I think this is logical, and how it relates to the
builtin types of C++.

Assume we only had internal types (as template parameters), then the above
is no issue and we would write templates like:

template < class T >
class A {
  T foo;
  //...
};

where T could be anything and a seperate class A<T> needs to be generated
for every T (even the size of A changes as a function of T).

However, many practical classes only use pointers to a type:

template < class T >
class A {
  T *foo;
  // ...
};

This *could* be precompiled. Just replace the pointer (T*) by (void*), and you
get:

class A {
  void *foo;
  // ...
};

Where only type checking is needed, during compile time of new sources which
use class A<T>.  The template could be compiled just once and be part of a
shared library, and only the header file containing the definition of A<T>
would make A different from the last class A with the (void*).
The linker couldn't care less about what type the pointer is.

Now realize that a (void*) is a "pointer to (a base class of) all types",
where the 'base class' is empty.  Lets call this base class 'internal', then
the above - using my new notation - would read:

template < class internal::T >
class A
{
 T *foo;
 // ...
};

Restricting T to only internal types ;).

>>> Ofcourse, for user made types (classes), we have the exact same reasoning.
>>> It is however an *extention* of the above.  Consider the following
>>> example:

class B {
public:
  B& b(int i) { /* ... */ }
  // ...
};

template < B::T >
class A {
public:
  B& foo(T& f) { return f.b(4); }
  // ...
};

>>> Then f, being a B (and ofcourse ONLY using methods of B), can be
>>> precompiled.  All we have to do is compile:

class A {
public:
  B& foo(B& f) { return f.b(4); }
  // ...
};

>>> and let the compiler only worry about the extra information included in
>>> the template definition when compiling NEW sources using class A.


I realize that it is probably not possible to change the standard anyway
(it's too late for that), but I'd like to see at least some discussion
about this idea.


Carlo

--
---------------------------------------------------------------------------
Junior Technology Expert  | Getronics Software (http://gso.getronics.nl)
      E-mail: carlo@ims.gso.getronics.nl  | Tel.nr: +31-20-4306519
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]