C++标准库如何与不同的C++标准进行链接

6
我正在使用Cygwin(GCC v4.5.0)编译一个项目,遇到了奇怪的链接问题。希望有经验的人能够帮助解决。
错误信息如下: “undefined reference to std::basic_string, std::allocator >::basic_string(std::basic_string, std::allocator >&&)”
然而,只有在我使用gcc编译器标志“-std=c++0x”时,链接才会失败。如果不指定标准,则会成功。
一些注意事项:
1. 我用编译器标志“-lstdc++”手动通知gcc链接标准库。 2. 符号依赖性来自Boost库头文件(v.1.45.0):“boost::units::detail::utility.hpp”,函数为“std::string demangle(const char* name);”。 3. 使用MinGW gcc v4.5.0编译应用程序并链接成功。
问题如下:
1. 编译的标准库通常是否包含不同的符号? 2. 在GCC中,不同的C++标准是否会更改符号的名称重整? 3. 为什么链接器找不到std::basic_string的符号,而我可以保证它能找到libstdc++.a?
谢谢大家的帮助。
-JT

你的错误文本有问题。你是直接引用的吗?它没有任何意义。 - Edward Strange
@Noah:你是指“&&”吗?那看起来像是C++0x中的右值引用符号。 - David Thornley
1个回答

8
是的,标准和技术报告的新版本对标准库的内容进行了许多更改。您提到的函数(std :: string移动构造函数)是在C ++ 0x的标准库中新添加的。
标准的版本不影响名称修饰,尽管编译器版本会影响,并且需要更新的编译器以获得更好的C ++ 0x支持,因此它可能与此有关。
您可能正在使用过旧的libstdc ++版本。
编辑:基本故障排除:
$ 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> >&&)

这确实看起来有点奇怪。定义 std::wstring(即 std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>)是正确的,但窄版则不是。由于它只是一个typedef,因此名称 std::string 不应该在编译器名称重整阶段存在。然而,我在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> >&&)

嗯...这可能表明Cygwin版本的GCC v.4.5.0有缺陷? - J T
1
当您安装g++的实验版本时,是否也获得了libstdc++6-devel的v4.5版本?我刚刚在我的答案中添加了检查该版本所需的命令。 - Ben Voigt
1
啊,太好了,这解决了问题。非常感谢你,Ben。我之前没有安装libstdc++6-devel。不幸的是,Cygwin没有提供更多的文档来使这个过程更少出错。 - J T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接