拿简单的代码:
#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
函数 'foo' 被标记 - 这是完全正确的。在它的名字中没有 ABI 的迹象,但它使用依赖于 ABI 的 std::string。
函数“bar”没有标记。它也可以,因为它的签名通过 std::__cxx11 命名空间直接引用了 ABI。
但是 'operator std::string' 也被标记了。为什么?它的名称中已经包含“std::__cxx11”。
并且 'std::string::empty' 没有标记。 - 对我来说合乎逻辑。
如果我们用 clang++(3.9,svn 的主干)重复相同的步骤,我们会看到一些不同的图片:
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
除了'operator std::string',一切都一样。
谁是 g++ 或 clang++?我认为 clang 行为更合乎逻辑。
但是,我们已经在各种 Linux 发行版中使用 g++ 编译了一些库。所以可能是要改变的 clang 。
我已经在 llvm 中提交了这个错误。但是还是有疑问——是clang还是gcc的bug?
最佳答案
ABI 标记是 Clang 仅在必要时模拟的 GCC 功能,GCC 是规范引用。
关于c++11 - 运算符 std::string() 上的 abi_tab:clang++ 和 g++ 中的不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38389272/