Topic: template instantiation
Author: Dave Moore <sponk@geocities.com>
Date: 1998/05/29 Raw View
I am having problems separating interfaces from implementations when
using templates. Since C++ compilers do not generate object code until
a template is instantiated for a given class, it makes for huge header
files when these templates are needed for user-defined types since the
function bodies need to be specified in the header file itself. If the
function bodies are NOT included in the header and the .h and .c files
are used to separate interface from implementation in the standard
fashion, this ALWAYS generates linker errors on EVERY compiler I have
tried.
As I understand it, this is because the compiler will only generate
object for the template functions when they are DEFINED in the same
scope as the declaration which represents the attempt to instantiate the
template. Now, I have seen it suggested (on various newsgroups) that
this can be circumvented somewhat by using separate interface
(declaration) and implementation (definition) header files. The idea is
that a separate compilation unit (which #includes the larger
implementation header containing the function definitions) is used to
instantiate the template with a typedef for each class it will be needed
for. Supposedly, this will generate a full set of object code for each
class which can then be linked to other compilation units which only
have to include the (smaller) interface headers that only contain the
template function declarations.
This technique sounds good in theory BUT IT DOESN'T WORK!! The
template alone is not sufficient to generate any object code on any
compiler I have tried. I suspect this is because it is a kludge, and
clearly it is typically desirable for compilers to be optimized in this
fashion ... functions which are not needed should not cause any object
code to be generated. In fact, when I read Bjarne Stroustrop's (C++ 3rd
edition) book, he says that a keyword "export" can be used to explicitly
make templates accessible from other compilation units. So all this
messing about with two sets of header files should be unneccesary.
Unfortunately this "export" keyword is not implemented on any compiler I
have come across thus far (I have only tried those which are available
for PC's ... I am fairly sure the UNIX support is there, but I don't
have a UNIX system ... which is my primary problem I suppose).
Anyway, I apologize for the long post but I felt this problem needed
a detailed description. I am hoping that some kind, knowledgeable
soul(s) out there will be able to suggest solutions and/or workarounds
for this troubling problem. Thanks in advance.
Dave Moore
unc-chapel hill
dtmoore@email.unc.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Silvio Bierman" <idfix@wxs.nl>
Date: 1998/05/29 Raw View
This item has been discussed many times. Until the compilers supporting the
export keyword arrive, we are stuck with three options:
A
Include all definitions in the headerfiles, which works but makes for slow
compiles and messy headers
B
Use a Unix C++ compiler which supports link-time instantiation. This works
also, but these compilers are usually terribly slow and support some ancient
C++ which is not acceptable (for me at least...)
C
Separate the implementation and the declaration, and use explicit
instantiation on the required anstantiations. This works only if you are
willing to instantiate everything by hand, which can be a very lengthy job,
especially when templates use other templates for their implementations.
Hope this helps
Silvio Bierman
Dave Moore wrote in message <356DC2D1.A1B3330C@geocities.com>...
> I am having problems separating interfaces from implementations when
>using templates. Since C++ compilers do not generate object code until
>a template is instantiated for a given class, it makes for huge header
>files when these templates are needed for user-defined types since the
>function bodies need to be specified in the header file itself. If the
>function bodies are NOT included in the header and the .h and .c files
>are used to separate interface from implementation in the standard
>fashion, this ALWAYS generates linker errors on EVERY compiler I have
>tried.
> As I understand it, this is because the compiler will only generate
>object for the template functions when they are DEFINED in the same
>scope as the declaration which represents the attempt to instantiate the
>template. Now, I have seen it suggested (on various newsgroups) that
>this can be circumvented somewhat by using separate interface
>(declaration) and implementation (definition) header files. The idea is
>that a separate compilation unit (which #includes the larger
>implementation header containing the function definitions) is used to
>instantiate the template with a typedef for each class it will be needed
>for. Supposedly, this will generate a full set of object code for each
>class which can then be linked to other compilation units which only
>have to include the (smaller) interface headers that only contain the
>template function declarations.
> This technique sounds good in theory BUT IT DOESN'T WORK!! The
>template alone is not sufficient to generate any object code on any
>compiler I have tried. I suspect this is because it is a kludge, and
>clearly it is typically desirable for compilers to be optimized in this
>fashion ... functions which are not needed should not cause any object
>code to be generated. In fact, when I read Bjarne Stroustrop's (C++ 3rd
>edition) book, he says that a keyword "export" can be used to explicitly
>make templates accessible from other compilation units. So all this
>messing about with two sets of header files should be unneccesary.
>Unfortunately this "export" keyword is not implemented on any compiler I
>have come across thus far (I have only tried those which are available
>for PC's ... I am fairly sure the UNIX support is there, but I don't
>have a UNIX system ... which is my primary problem I suppose).
> Anyway, I apologize for the long post but I felt this problem needed
>a detailed description. I am hoping that some kind, knowledgeable
>soul(s) out there will be able to suggest solutions and/or workarounds
>for this troubling problem. Thanks in advance.
>
>
>Dave Moore
>
>unc-chapel hill
>
>dtmoore@email.unc.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 ]
>[ --- Please see the FAQ before posting. --- ]
>[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
>
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dave Moore <sponk@geocities.com>
Date: 1998/05/29 Raw View
Thanks for the prompt reply:
I just got done talking to a computer science prof. and he said
basically the same thing ... except that he recommended that I rewrite
my whole library structure without the templates!! This is not a
feasible option right now so I will probably opt for the intensely
kludgy explicit instantiation method. I figure I can just get some beer
and turn off my brain and crank it out ... I have lots of templates and
derived templates though, so it will take several hours.
It seems to me that, anticipating this type of problem, compiler
writers could easily provide a pragma which would toggle explicit
instantiation from a simple typedef statement. I agree that it should
not be the default behavior, but there are situations (like this one)
where it would save a lot of time. To be explicit ... I would like to
see a pragma which tell the compiler to generate *ALL* the object code
for an instantiation from a typedef statement. Does anyone know if
there is a compiler which has this option?? Thanks again,
Dave Moore
Chemistry Department
UNC Chapel Hill
dtmoore@email.unc.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jason Merrill <jason@cygnus.com>
Date: 1998/06/01 Raw View
>>>>> Dave Moore <sponk@geocities.com> writes:
> To be explicit ... I would like to
> see a pragma which tell the compiler to generate *ALL* the object code
> for an instantiation from a typedef statement.
Why not use explicit instantiation directives?
template class foo<bar>;
Jason
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dave Moore <sponk@geocities.com>
Date: 1998/06/02 Raw View
> > To be explicit ... I would like to
> > see a pragma which tell the compiler to generate *ALL* the object
> code
> > for an instantiation from a typedef statement.
>
> Why not use explicit instantiation directives?
>
> template class foo<bar>;
>
Apparently because I am ignorant. I had seen such declarations before
but I had gotten the impression that they were not part of the language
standard (also these explicit instantiations did not work on an older
verion of my compiler). Since it is important for my code to be
portable, I was loath to include anything that might be a "perk" from a
given compiler. However, after I saw your post I tested that syntax on
several compilers and it seems to work fine. I also checked
Stroustrup's book ("the C++ Programming Language", 3rd ed.) and he does
consider it to be part of the language. So, thanks very much for the
tip!
Dave Moore
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Richard Nemec" <rnemec@cascadenet.com>
Date: 1998/06/03 Raw View
Dear Dave,
I can suggest you a solution somewhere between your's and your
CS prof's.
1. Explicit instantiation works (it's really part of the language) BUT
it generates LOT of code. (Yes, if you use space optimizations
you will be ok after linking, but after a couple of months of
refining your library, the object files will be REALLY BIG.
And not only library object files - if your library will be used
by other developers (YourTemplate<MyClass>). )
1a. It is not considered to be a good design having lot of code
in template classes. (Usually :-)
2. If you avoid using templates your code will be usually less
type-safe (read Scott Meyers books - they are great).
It's bad, too.
3. Try to thing about some rewriting of your library structure:
- using non-template base classes for your template classes
often helps - there you can place lot of code (that goes into
object files) and template classes serve only as a type-safe
interface to them (with a few neccessary code - like "new T").
- if your template arguments are expected to be subclasses
of ONE fixed class, it will really help with design of the base
non-template classes
- if the arguments are subclasses of more fixed classes it may
also help (but you usually have to play with overloading)
- otherwise this solution may or may not help :-)
4. if you are not sure of proper design you can contact me with
more details
Richard
P.S. There are more issues concerning using virtual/non-virtual
functions etc.
Dave Moore wrote in message <3573F612.5B999BDB@geocities.com>...
>> template class foo<bar>;
>>
>Stroustrup's book ("the C++ Programming Language", 3rd ed.) and he does
>consider it to be part of the language. So, thanks very much for the
>tip!
--
Richard Nemec, Cascade Systems Inc, e-mail: rnemec@cascadenet.com
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ming Feng Gu <mfgu@cuphy3.phys.columbia.edu>
Date: 1998/05/14 Raw View
here is my question,
define two template classes a,b
template <class T>
class a{
...
T m1;
void func_of_a(void){
m1.func_of_b();};
...
};
and
template <class T>
class b{
......
T m2;
void func_of_b(void){...};
......
};
is it possible to instantiate template a of type, say, b<int>?
a<(b<int>)> cause error flag at compiling time, while the following pass
the compile,
typedef b<int> int_b;
foo=a<int_b>;
but at linking time, func_of_b used in func_of_a is flagged as undefined
symbol.
is there anyway out of this? i appreciate any suggestions. please send me
an email as well while posting the reply.
ming gu
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Yotam Medini <yotamm@tmai.com>
Date: 1996/12/17 Raw View
Recently, I was working on a project using C++ with templates.
Encouraged by the STL being accepted as a standard I was excited
to use it.
Alas, I had to deal with porting the package to various UNIX platforms.
Because of 3rd party libraries our applications link with I was forced to
use native compilers.
Side Remark:
I vowed, that if I will ever have a decision power,
I will _refuse_ to buy or commit to a new 3rd party C++-library
that does not have a supported (GNU) g++ compiled version
on all major platforms.
Basically, template instantiation introduces the following problems
when the compiler does not generate inline code:
* When to instantiate -- compile time or link time?
* Where to put the object code.
This is also dependent on the previous When-question.
Several methods:
+ Augment each object-module with instantiations code needed
and have a smart linker decide what to pick and what to discard.
+ Have a template repository, with database of status and dependencies.
+ Manual instantiation controlled by the template user
in (a) special module(s).
See also 'Where's the Template?' in gcc documentation (gcc.info)
http://www.cygnus.com/library/gcc/usegcc_107.html#SEC110
The following consideration should be taken:
+ Complexity of satisfying referenced instantiation.
+ Complexity of avoiding duplicate instantiation.
+ Complexity of avoiding unneeded instantiation linked in.
+ Compilation and linkage speed while dealing with automatic instantiation.
+ Possibility of providing a library that uses but does not export templates.
All instantiation referenced internally are needed to be supplied.
Application should be able to:
* Know nothing about the library templates.
Application might even have its startup routine coded in C or fortran
provided the library does not assume static initialization.
* Use some template instantiation used by the library
without fighting linker duplication problems.
Needless, to say that each UNIX compiler, introduces its own
deficiencies. But in the case of template instantiation - C++ compiler
limitations result with problems of higher magnitude.
Porting code that uses templates leads to class member exposures, and
lots of type-instantiation specific maintenance which is ironically the
problem templates were meant to solve!
- - -
My suggestion to the C++ standard committees.
---------------------------------------------
If C++ templates have the desire to survive, it is not enough to provide
semantics of the code, there ought to be guidelines for usage and
implementation. I suggest that a (non trivial) package of code that uses
all standard template features will be established. Such package should
provide a benchmark for testing and measuring the following capabilities:
* Library split among different directories.
* Template class member definition may be split to different source files.
The reason is to avoid linking unnecessary code.
* Automatic instantiation.
* Manual instantiation.
* Order of compilation time and linkage time (t) depending
on number of instantiations (n).
The amount of time O(t) should not be worse than O(n*log(n)).
Repository database access should not be a linear search...
giving quadratic time for linkage.
* Provide a library that uses templates, some of which are exposed
some are hidden from application.
The C++ community should encourage every C++ compiler
to show how it handles the problems of such an established package.
Yotam Medini -----------------------------:)--h--o--m--e-----------------\
<< Technology Modeling Associates, Inc. >> 1144 Craig Dr. // Lost |
<< 595 Lawrence Expy. Sunnyvale, CA 94086 >> San Jose, CA 95129 // my |
<< yotam_medini@tmai.com -3935 >> yotam@sj-coop.net // smart |
<< (408) 328-3887 [fax (408)3280940] >> (408) 257-0840 // quote |
<< http://www.blueneptune.com/~yotam/ |
[ 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 ]