C++ std library linking with different C++ standards

12,901

Yes, both new revisions of the standard and technical reports make many changes to the content of the standard library. The function you referenced (std::string's move constructor) is newly added in C++0x's standard library.

The version of the standard does not affect name mangling, although the compiler version does, and newer compilers are needed for better C++0x support, so it could appear to be related.

You are probably using too old a version of libstdc++.

EDIT: Basic troubleshooting:

$ find /usr -name libstdc++.a
/usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a

$ cygcheck -f /usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a
libstdc++6-devel-4.5.0-1

$ nm -C /usr/lib/gcc/i686-pc-cygwin/4.5.0/libstdc++.a | grep basic_string | grep '&&'
00000000 T std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&)
00000000 T std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&)
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::assign(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
00000000 T std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::operator=(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)

This does indeed look a little funny. The definitions for std::wstring (i.e. std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >) look correct, the narrow versions do not. The name std::string shouldn't ever have survived to the mangling stage, since it's just a typedef.

However, I get the same output on linux:

% find /usr -name libstdc++.a
/usr/lib64/gcc/x86_64-pc-linux-gnu/3.4.6/libstdc++.a
/usr/lib64/gcc/x86_64-pc-linux-gnu/3.4.6/32/libstdc++.a
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/libstdc++.a
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/32/libstdc++.a

% nm -C /usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.2/libstdc++.a | grep basic_string | grep '&&'
0000000000000000 W std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&)
0000000000000000 W std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&)
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::assign(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
0000000000000000 W std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::operator=(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&&)
Share:
12,901

Related videos on Youtube

J T
Author by

J T

Updated on May 17, 2022

Comments

  • J T
    J T almost 2 years

    I am compiling a project using Cygwin (GCC v4.5.0) and I'm having an odd linker problem. I am hoping somebody with some expertise can help.

    Error: undefined reference to std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)

    However, the linking only fails when I compile with the gcc compiler flag: -std=c++0x It succeeds when I don't specify the standard.

    Some notes:

    1. I am informing gcc to link the standard library manually with the compiler flag: -lstdc++
    2. The symbol dependency is originating from a Boost library header file (v.1.45.0): boost::units::detail::utility.hpp, function: std::string demangle(const char* name);
    3. The application compiles and links properly using MinGW gcc v4.5.0.

    Questions:

    1. Does the compiled standard library usually contain different symbols for different C++ standards?
    2. Does the name mangling of symbols change with different C++ standards in GCC?
    3. Why can't the linker find the symbols for std::basic_string when I can guarantee that it can find libstdc++.a?

    Thanks in advance everyone.

    -JT

  • J T
    J T over 13 years
    Hmm.. so that would indicate that perhaps the cygwin version of GCC v.4.5.0 is flawed?
  • Ben Voigt
    Ben Voigt over 13 years
    When you installed the experimental version of g++, did you also get v4.5 of libstdc++6-devel? Just added to my answer the commands necessary to check that version.
  • J T
    J T over 13 years
    Ahh that fixes it. Thanks a lot Ben. I had not installed libstdc++6-devel. Its unfortunate that cygwin doesn't provide more documentation to make the process less error prone.