help-gplusplus
[Top][All Lists]
Advanced

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

Re: Explicit Template Instantiation


From: Paul Pluzhnikov
Subject: Re: Explicit Template Instantiation
Date: 01 Dec 2004 18:25:06 -0800
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Artificial Intelligence)

Garrett Kajmowicz <garrett@garrett.dyndns.biz> writes:

> I am attempting to implement the standard C++ library for embedded systems
> (cxx.uclibc.org).  So far so good.  Most of the code is in templates.  As
> such, I'm trying to instantiate as much of the likely code (such as
> std::string) into the library itself so that there is less code
> duplication.  This works for much, but not all, of the code.

What exactly "works" and how do you know that it does (from what
you described, it shouldn't).

> For example, in a test piece of code that I have, I have a version in the
> library and a version compiled into the executable after linking.

That's what *should* be happening, unless you make specific effort
for this not to happen. If you do make such effort, you have not
described it. 

Also note that "the library" can mean either a DSO or an
archive library, and what should be happening certainly depends on
what kind of library you are using. [Looks like it is a DSO].

> There are also minor differences in the assembler code which I
> cannot account for.

Looks like "library code" was compiled with -fno-exceptions, while
the application code with -fexceptions.

> C++ code:
> 
> virtual ~basic_ios(){ }
> ~ios_base() { }
> ~Init() is forced into the library (by me) because it isn't a template

That's not C++ code. That's a tiny snippet, that can't be compiled.
If you want help, you should work a bit more to produce a minimal
test case that can be *compiled*.

> Why is the version in the application actually there?  

Why should it not be?

The compiler, at the time of compilation of the application, has
no way of knowing whether there will be any library at link time,
which will define _ZNSt9basic_iosIcSt11char_traitsIcEED1Ev.

So it writes a weak instance of the above into *every* compilation
unit that may need it.

On ELF platforms, it puts that code into a 
.gnu.linkonce.t._ZNSt9basic_iosIcSt11char_traitsIcEED1Ev
section, and marks it with a special LINK_ONCE_DISCARD flag,
which allows the linker to keep only one copy of that section in
the final a.out or elf.so

> How do I get the application to use the library version?

One way is to provide specializations for the templates that you
do provide in the library, and "hide" the method bodies for them,
so the compiler could not write instantiation even if it wanted to.

For example:

template <typename T> struct Foo
{
   methodA() { ... }
   methodB() { ... }
};

template <> struct Foo<char>
{
   methodA(); // body of Foo<char>::methodA() provided in the library
   methodB(); // ditto
};

Now the client code using e.g. Foo<char>::methodA will have no
choice but to go to the library for its body, but would still be
able to use e.g. Foo<int> (which you do not provide in the library).

If this sounds like a lot of pain, it probably is.

Cheers,
-- 
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.


reply via email to

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