2016-07-15 2 views
4

Возьмем простой код:abi_tab на оператора станд :: строка(): Несовместимость в лязг ++ и г ++

#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, но он использует std :: string, который зависит от ABI.

Функция «бар» не отмечена. И это также нормально, так как его подпись имеет прямую ссылку на ABI через пространство имен std :: __ cxx11.

Но «оператор std :: string» также отмечен. Зачем? У него уже есть «std :: __ cxx11».

И «std :: string :: empty» не помечен. - Логично для меня.

Если мы повторяем одни и те же действия с лязгом ++ (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 

Все то же самое, но «оператор станд :: строка».

Кто здесь, g ++ или clang ++? Я думаю, что поведение клана более логично.

Однако у нас уже есть библиотеки, скомпилированные с g ++ в различных дистрибутивах Linux. Так что, вероятно, это будет изменено.

Я отправил эту ошибку в llvm. Но все еще есть сомнения - это clang или gcc bug?

+0

Просто спрашивая из любопытства, почему это имеет значение для вас? – Arunmu

+0

Это имеет значение для меня, поскольку я не могу скомпилировать свой проект с clang, только gcc. –

ответ

1

Маркировка ABI, являющаяся функцией GCC, которая только эмулирует по необходимости, GCC является канонической ссылкой.

0

Это странно. clang 3.8 с https://reviews.llvm.org/D18035 работал правильно для меня. Этот патч был включен в 3.9, но он больше не работает. Я не могу найти никаких объяснений.

undefined reference to `libconfig::Setting::operator std::__cxx11::basic_string, std::allocator >() const
+0

Также похоже, что clang3.8 добавляет '__cxx11', но clang5.0.0 не делает – dashesy

0

лязг 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.

Смежные вопросы