运算符std :: string()上的abi_tab:clang ++和g ++中的不兼容性

时间:2016-07-15 06:30:51

标签: c++11 g++ clang++

采用简单的代码:

#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?

3 个答案:

答案 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