Topic: Template instantiation question (long)
Author: bill@amber.ssd.csd.harris.com (Bill Leonard)
Date: 26 Sep 1994 18:15:10 GMT Raw View
In article <CwFonp.146@borland.com>, pete@genghis.interbase.borland.com (Pete Becker) writes:
> In article <35m07m$j0s@ixnews1.ix.netcom.com>,
> Phil Goodwin <PGoodwin@ix.netcom.com> wrote:
>
> How would you implement a library that uses certain templates? If you
> put all of your template instantiations in the same file, they all get linked
> in, regardless of which ones are actually used. If you have two libraries that
> do this, you may well end up with duplicate definitions.
> -- Pete
How is this different from managing member functions of classes? If you
put all the member functions in one .c file, then you get all of them
linked in whether you use them all or not. If you partition them, then you
have to come up with the partitioning.
Same thing applies to template instantiations, but on a different level.
Lots of people seem to think that the compiler and linker *have* to solve
this problem, but I don't. It's very similar to what we do now with
partitioning functions among source files. So what's so hard?
I agree it may be somewhat tedious in a very complicated application, but
so far the "automated" solutions seem to me to be just as complicated,
plus their results are seldom understood -- that is, the programmer has little
idea where instantiations were placed or even which templates were
instantiated for which arguments.
Personally, I'd rather have control and knowledge of these things. If I
am forced to instantiate every template manually, then I can catch cases where
they should *not* have been instantiated at all, plus I can manage the
placement of code.
Another factor that hasn't been mentioned so far is static initializers.
If a template instantiation results in defining a static variable with a
constructor, one must be careful about when that constructor is called. As
we should all know by now (given the numerous discussions in this
newsgroup), there is no language-defined mechanism for controlling the
order in which static variables in separate source files are initialized.
Most of us who run into this problem invent extra-language solutions. But
if you have zero control over template instantiation, how are you going to
control the order of initialization? Answer: You're not.
--
Bill Leonard
Harris Computer Systems Division
2101 W. Cypress Creek Road
Fort Lauderdale, FL 33309
Bill.Leonard@mail.csd.harris.com
These opinions and statements are my own and do not necessarily reflect the
opinions or positions of Harris Corporation.
------------------------------------------------------------------------------
More people run Windows on their home computers than on any other home
appliance.
------------------------------------------------------------------------------
Author: PGoodwin@ix.netcom.com (Phil Goodwin)
Date: 20 Sep 1994 06:41:58 GMT Raw View
>> >I know at least some C++ compilers provide such a mechanism, at least as an
>> >option. If I owned one of those compilers (which I don't), I would opt for
>> >that mechanism.
>> >
>>
>> No, you wouldn't. Not after struggling with the dependencies in your
>> first complex project. This works fine for simple cases, but once you start
>> using templates that use other templates the details become overwhelming.
>
>"First complex project"? Ha ha ha ha ha ha! :-) :-)
>
>Seriously, I may not be a genius, but I am pretty smart. I think I could
>figure it out. :-)
>
>Since I don't have a compiler that supports templates (yet), I use macros
>as the poor man's template mechanism. In effect, I am already using the
>scheme I outlined above, with no problems.
<Snip>
That's what I've been doing too. It seems to me that you could
introduce a template declaration syntax without too much trouble by
simply removing the 'template' keyword from the instantiation request
syntax. Such a declaration could expand to the declaration for the
template. This structure could be used over and over again and, thus,
would be suitable for use in a header file. I would put all of the
template instantiations in the same file in order to simplify code
maintenence. I would also like to make multiple instantiations an error
condition whether they were found at compile time or link time. This
becomes a major problem, however when you want to link together two
separately developed modules that each rely on -- and contain -- the
same template instantiation. You could use namespaces to circumvent
this problem, but that would be kind of ugly because you would end up
with duplicate versions of identical code embedded in your program --
not exactly efficient. An alternative would be to make linkers a little
smarter so that they could be told that a certain module might be
duplicated later in the link process and that these duplicates can be
safely ignored. I wonder if there is any way to do this with a
'standard' C linker(?) Or if it would be possible to add this
'enhancement' to a linker while still allowing it to link normal C
object files.
As far as I can see the duplicate definition thing is the major
issue involved with making programmer instantiation of templates
mandatory. The other issue that gets mentioned alot is template
interdependance. I think that using a declaration syntax would help
solve this problem by reducing it to a fairly common type of compiler
error: use of an undefined identifier. This error would be issued when
the compiler is trying to instantiate an instance of a template that
requires the presence of another template. To get rid of the error you
have to make sure that a declaration for the needed template instance
is available to the scope in which the template is being instantiated
and you need to make sure that the needed template instance is actually
instantiated in some module that will eventually be linked with, and
visible, to the current module. None of this is any harder than adding
any other new function or class to a project. In fact it's easier
because the template is providing the body of the code so you don't
have to. Alternatively the template could be allowed to do all of this
work by allowing nested instantiation. I don't really like this
solution, however, because it could result in a lot of code being
generated 'invisibly', and it could potentially cause a great deal of
duplicate code generation that would waste time and make a big mess to
be cleaned up at link time.
I think that this approach to tempates would minimize compiler and
linker complexity, provide orthagonality to the rest of the language,
and enhance code maintainability through an enforced accounting of all
resources generated and used. The cost of using this approach is
essentially the addition of the template declaration syntax. The
current methods of template instantiation could be phased out gradually
through use of warning messages for use of undeclared template
instantiations. Of course compiling code under a compiler that supports
only explicit instantiation would produce a slew of unresolved
externals at link time. However, I think that it would be fairly easy
to produce a tool that would generate the needed template instantiation
module directly from the source code for a project. This module could
then be compiled and linked into the rest of the project without
changing any of the original source code.
This idea (if not it's explaination) seems pretty simple to me. Does
it have any real problems?
Phil Goodwin PGoodwin@Netcom.com
Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Tue, 20 Sep 1994 15:07:01 GMT Raw View
In article <35m07m$j0s@ixnews1.ix.netcom.com>,
Phil Goodwin <PGoodwin@ix.netcom.com> wrote:
>>> >I know at least some C++ compilers provide such a mechanism, at least as an
>>> >option. If I owned one of those compilers (which I don't), I would opt for
>>> >that mechanism.
>>> >
>>>
>>> No, you wouldn't. Not after struggling with the dependencies in your
>>> first complex project. This works fine for simple cases, but once you start
>>> using templates that use other templates the details become overwhelming.
>>
>>"First complex project"? Ha ha ha ha ha ha! :-) :-)
>>
>>Seriously, I may not be a genius, but I am pretty smart. I think I could
>>figure it out. :-)
>>
>>Since I don't have a compiler that supports templates (yet), I use macros
>>as the poor man's template mechanism. In effect, I am already using the
>>scheme I outlined above, with no problems.
><Snip>
>
>I would put all of the
>template instantiations in the same file in order to simplify code
>maintenence.
How would you implement a library that uses certain templates? If you
put all of your template instantiations in the same file, they all get linked
in, regardless of which ones are actually used. If you have two libraries that
do this, you may well end up with duplicate definitions.
-- Pete