采用简单的代码:
#include <string>
class C{
public:
operator std::string ()const;
};
C c;
std::string foo(){return c;}
bool bar(std::string const&s){return s.empty();}
让我们看一下符号名称:
g++ -std=c++11 -c sample.cpp
nm -C sample.o
我们会看到这样的符号:
bar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
foo[abi:cxx11]()
C::operator std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >[abi:cxx11]() const
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::empty() const
功能&#39; foo&#39;被标记 - 这是完全正确的。在它的名字中没有ABI的迹象,但它使用了依赖于ABI的std :: string。
功能&#39; bar&#39;没有标记。它也可以,因为它的签名通过std :: __ cxx11命名空间直接引用ABI。
但是&#39;运营商std :: string&#39;也被标记。为什么?它已经&#39; std :: __ cxx11&#39;以它的名字。
&#39; std :: string :: empty&#39;没有标记。 - 对我来说很逻辑。
如果我们用clang ++(3.9,svn的trunk)重复相同的步骤,我们会看到一些不同的图片:
bar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
foo[abi:cxx11]()
C::operator std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >() const
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::empty() const
一切都是一样的但是&#39;运营商std :: string&#39;。
谁在这里g ++或clang ++?我认为铿锵行为更合乎逻辑。
但是我们已经在linux的各种发行版中使用g ++编译了一些库。所以可能有必要改变。
我在llvm中提交了这个bug。但仍然有疑问 - 它是clang还是gcc bug?
答案 0 :(得分:1)
ABI标记是一种GCC功能,只有在必要时才能模仿,GCC是规范参考。
答案 1 :(得分:1)
clang 4.0和GCC 7.2现在生成相同的错位符号:
bar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
foo[abi:cxx11]()
C::operator std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >() const
GCC似乎有一个错误的错误。
答案 2 :(得分:0)
这很奇怪。 clang 3.8与https://reviews.llvm.org/D18035正常工作对我来说。这个补丁在3.9中已经被强调,但它不再有效。我找不到任何解释。
undefined reference to `libconfig::Setting::operator std::__cxx11::basic_string, std::allocator >() const