C ++ std库与不同的C ++标准链接 [英] C++ std library linking with different C++ standards

查看:226
本文介绍了C ++ std库与不同的C ++标准链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Cygwin(GCC v4.5.0)编译项目,我有一个奇怪的链接器问题。


错误:未定义引用 std :: basic_string< char, std :: char_traits< char>,std :: allocator< char> > :: basic_string(std :: basic_string< char,std :: char_traits< char>,std :: allocator< char>&&&&&)


但是,当我使用gcc编译器标志编译时,链接失败:
-std = c ++ 0x

一些注释:



ol>
  • 我通知gcc手动链接标准库和编译器标志: -lstdc ++

  • 符号依赖性源于Boost库头文件(v.1.45.0):
    boost :: units :: detail :: utility.hpp,function:std :: string demangle const char * name);

  • 应用程序使用MinGW gcc v4.5.0正确编译和链接。

  • 问题:


    1. 编译标准库通常包含不同的C ++标准符号?

    2. 为什么链接器找不到的符号 std :: basic_string 当我可以保证它可以找到 libstdc ++。a

    先感谢大家。



    -JT

    解决方案

    是的,标准和技术报告的新修订版对标准库的内容进行了很多更改。您在C ++ 0x的标准库中新添加了您引用的函数( std :: string move constructor )。



    标准的版本不会影响名称调整,虽然编译器版本,并且需要更新的编译器更好的C + + 0x支持,所以它可能似乎是相关的。 p>

    您可能使用的是旧版本的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>>&&& amp;)

    这看起来有点滑稽。 std :: wstring 的定义(即 std :: basic_string< wchar_t,std :: char_traits< wchar_t>,std :: allocator< wchar_t& > )看起来正确,窄版本没有。 std :: string 应该永远不会生存到磨损阶段,因为它只是一个typedef。



    然而,我在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>>&&& amp;)


    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

    解决方案

    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> >&&)
    

    这篇关于C ++ std库与不同的C ++标准链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆