help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Template instantiation in libraries


From: Guy Harrison
Subject: Re: Template instantiation in libraries
Date: Sat, 04 Dec 2004 09:01:29 GMT
User-agent: KNode/0.7.7

Garrett Kajmowicz wrote:

> In an attempt to cut down on the verbiage, I have been vague to the point
> that what I have said has been useless.  Here goes yet another attempt.
> 
> I am implementing the standard C++ library with the target being embedded
> systems.  Toward that end I am focusing on small code, lower memory
> usage, etc.  The standard C++ library is mostly templates.  In order to
> cut down on the amount of code being put into each and every executable
> being compiled, my intention was to instantiate many of the common
> versions of these templates with the intention of having the code be used
> out of the library and not be stored in the application.  Ex, I'm
> expanding much of the code for std::basic_string<char> (also known as
> std::string) because it is commonly used.
> 
> Unfortunately, even when the required code is placed in the library, the
> compiler/linker defaults to creating an instantiated copy of the template
> code in the executable as a weak symbol.

Never looked myself (as I've never had your problem)...

template <> //foo

..against a static lib works fine. It'll also work fine against a shared
lib, providided you don't 'dlopen' (Name Mangling).

> I can understand the idea of instantiating the template in the code (so
> that it is there if needed) and discarding duplicate copies (which is what
> happens).  However, I am unable to figure out how to get the compiler or
> (ideally) my library code to specify that in the binary that if a version
> of the function is available in the library it is being linked against
> that it should not be kept as a weak symbol.

Assuming compile time linkage, then "template <>" again.
 
> Is there any easy way to do this after-the-fact with binutils?

Don't go there. C++ name mangling remember. That aside, if you (say)
correctly instantiated "foo(wchar_t)" an app which sees that header...

//template <typename C>
//??? foo(const C*);
 
...will invoke linker errors for all cases for which "foo" hasn't been
instantiated for that type. In the case where "C" matches (and foo is
relevant) it *will* link.

> I have found a partial solution.  For cases where I want to provide
> certain versions of a template, I define a specialized version of the
> template in the header file, but put the definition in a .cpp file and
> compile it into the library.  This works and prevents instantiation when
> compiling.  However, it results in my having to have duplicate copies of
> the code kicking around, which is bad engineering and bad for
> maintenance, etc.

Have three files. foo.hpp (for declarations obviously), foo.cci (header
include) and foo.cpp (instantiation).

foo.cpp
#if defined(BUILDING_LIB)
 template <> ook(thingies); //instantiate
#endif

foo.hpp
#if defined(BUILDING_LIB)
# include "foo.cci"
#endif

> My solution to that problem was to create a dummy template class/function
> and put the real code in there.  Then the public functions call the
> private functions which actually do the work. This works but involves some
> workarounds and kind of kludgey.

If the code is in there and the declaration in foo.hpp matches it'll link.
Instantiate it in the lib and it *will* be there to link against.

> Hence my reason for trying to find ways to get the compiler/linker to use
> the library version of a symbol if available and thus discard the internal
> versions.

I don't follow. Hopefully it's irrelevent. I've been building libs aka the
above for years.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]