Boost logo

Boost :

From: Ulrich Eckhardt (uli_at_[hidden])
Date: 2005-02-14 14:51:54


On Monday 14 February 2005 08:00, Jonathan Turkanis wrote:
> Three iostreams tests are failing with the toolset msvc-stlport. All the
> unresolved symbols are specializations of standard library function
> templates.

almost, but see below...

> In the first case, the template argument is a user-defined type,
> but in all the other cases the template arguments are built-in types or
> standard library classes.

This doesn't matter.

> code_converter_test.cpp
>
> 1. __declspec(dllimport) public: __thiscall
> locale(locale const&, stateless_null_padded_codecvt*)

I get that one for other codecvt facets, too.

> 2. __declspec(dllimport)
> basic_string<unsigned short>::insert(
> struct _STL::_DBG_iter<class _STL::_Nondebug_string<unsigned short> >,
> unsigned short const*,
> unsigned short const*)
>
> 3. __declspec(dllimport)
> basic_string<char>::insert(
> struct _STL::_DBG_iter<_STL::_Nondebug_string<char> >,
> char const*,
> char const*)
>
> 4. __declspec(dllimport)
> basic_string<unsigned short>::basic_string(
> basic_string<unsigned short>::_DBG_iter<_STL::__vector<unsigned short> >,
> basic_string<unsigned short>::_DBG_iter<_STL::__vector<unsigned short> )

Never encountered these, but seems the same problem.

Anyhow, the problem is the compiler that has problems with code where
0. 1200 <= _MSC_VER < 1300 (this affects only VC6 and eVC4, AFAICT)
1. a class (not functions!) is imported from a library (e.g. _STL::locale)
2. the class contains template functions or ctors
3. inlining is deactivated

The workaround for STLport will be to separate the whole into an exported
baseclass without templates and a completely inline subclass that contains
the templates. This is work in progress or even already finished in the
upcoming STLport 5. It should be documented in the docs folder there, too,
provided I didn't forget...

The workaround for client code using older STLport versions is to provide
something that looks almost like a function specialization. For the locale
part, I copied the template ctor from the header to a file, added the
required _STL::locale:: and compiled that file for builds without inlining.
This then looked like (of the top of my head)
  template<>// maybe even without this line
  std::locale::locale<my_facet>(locale const& l, my_facet* f)
  { /* body copied verbatim */ }

However, this is a bit more complicated in reality:
a) above code on its own will complain that this ctor was not declared in
class locale. To work around this, provide a dummy function that uses this
ctor - for the compiler this will become the declaration. Alternatively, you
can put this code in the same file as you use the facet anyway, though
possibly (I don't know) not in a header.
b) determining whether inlining is active is non-trivial, to be honest I
haven't found a way yet, but also didn't search too hard. The problem is that
e.g. _DEBUG/NDEBUG can't be used, not only because you can still toggle
inlining by hand but also because some version of MSC 12 (the compiler
version included in e.g. VC6, but also in eVC4) simply don't do inlining -
only the versions supplied with the enterprise version support this. I
believe that the eVC4 versions (at least the version freely downloadable)
never do inlining.
Just wondering, but is there a way to force a function to not be inlined or
vice versa?

hth

Uli


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk