[iostreams] Link errors on msvc-stlport with dynamic runtime

Hi, Three iostreams tests are failing with the toolset msvc-stlport. All the unresolved symbols are specializations of standard library function templates. 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. The middle two look a bit suspicious, since debug and non-debug stuff is mixed together. I don't know anything about what functions STLPort defines in DLLs, so any help would be appreciated. Jonathan ---------------- Unresolved symbols (abbreviated): code_converter_test.cpp 1. __declspec(dllimport) public: __thiscall locale(locale const&, stateless_null_padded_codecvt*) 2. __declspec(dllimport) basic_string<unsigned short>::insert( struct _STL::_DBG_iter<class _STL::_Nondebug_string<unsigned short> >, unsigned short const*, unsigned short const*) newline_filter_test.cpp 3. __declspec(dllimport) basic_string<char>::insert( struct _STL::_DBG_iter<_STL::_Nondebug_string<char> >, char const*, char const*) wide_stream_test.cpp 4. __declspec(dllimport) basic_string<unsigned short>::basic_string( basic_string<unsigned short>::_DBG_iter<class _STL::__vector<unsigned short>
, basic_string<unsigned short>::_DBG_iter<class _STL::__vector<unsigned short> )

I have had the exact same problem when building the serialization library and have found no way around it. I tried definine the template instantiation in a separate module but it collided with some msvc problem. Robert Ramey Jonathan Turkanis wrote:
1. __declspec(dllimport) public: __thiscall locale(locale const&, stateless_null_padded_codecvt*)

Robert Ramey wrote:
I have had the exact same problem when building the serialization library and have found no way around it. I tried definine the template instantiation in a separate module but it collided with some msvc problem.
That's unfortunate. Unless somewone has a better idea, I guess I'll force static linking in the three problem cases. Jonathan
Robert Ramey
Jonathan Turkanis wrote:
1. __declspec(dllimport) public: __thiscall locale(locale const&, stateless_null_padded_codecvt*)

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

Ulrich Eckhardt wrote:
Jonathan Turkanis wrote:
Three iostreams tests are failing with the toolset msvc-stlport. All the unresolved symbols are specializations of standard library function templates.
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
<snip explanation of workarounds> Thanks for the detailed explanation! Unfortunately, while I could try to apply the workarounds to get the regression tests to compile, it would give library users a false sense of security since user-code likely won't instantiate these standard library member functions with the same template arguments as the tests. For example, the class stateless_null_padded_codecvt which showed up in the errors I listed is completely useless except for testing.
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?
You can keep a function from being inlined using #pragma auto_inline(off/on), but this does not apply to functions defined with the inline keyword or (I think) defined within the class definition. You can try to force inlining using __forceinline and pragma inline_recursion(on), but this is guaranteed to work always. Obviously it won't work for versions of the compiler which don't do inlining. Now that I understand the problem, I think I'm willing to document the library as being partially broken on msvc with STLPort without inlining. I'm glad to know it's not a bug in the iostreams library. Thanks for your help! Jonathan

FWIW - I took another shot at this and was unable to resolve the problem. Robert Ramey

Ulrich Eckhardt wrote:
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.
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
I tried to force inlining by adding the requirements <msvc-stlport><*><cxxflags>-Ob2 or <msvc-stlport><*><inlining>on, but neither solved the linking problems. In order to get all the tests to link I had to add <msvc-stlport><*><runtime-link>static. Jonathan
participants (3)
-
Jonathan Turkanis
-
Robert Ramey
-
Ulrich Eckhardt