Связывание библиотеки C ++ std с различными стандартами C ++ - PullRequest
6 голосов
/ 26 января 2011

Я компилирую проект с использованием 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 Успешно, когда я не указываю стандарт.

Некоторые примечания:

  1. Я сообщаю gcc, чтобы вручную связать стандартную библиотеку с флагом компилятора: -lstdc++
  2. Зависимость символов происходит из файла заголовка библиотеки Boost (v.1.45.0): boost::units::detail::utility.hpp, function: std::string demangle(const char* name);
  3. Приложение правильно компилируется и связывается с использованием MinGW gcc v4.5.0.

Вопросы:

  1. Содержит ли скомпилированная стандартная библиотека разные символы для разных стандартов C ++?
  2. Меняется ли искажение имен символов в соответствии с разными стандартами C ++ вGCC?
  3. Почему компоновщик не может найти символы для std::basic_string, когда я могу гарантировать, что он может найти libstdc++.a?

Заранее всем спасибо.

-JT

1 Ответ

8 голосов
/ 26 января 2011

Да, как новая редакция стандарта, так и технические отчеты вносят много изменений в содержимое стандартной библиотеки.Функция, на которую вы ссылались (std::string конструктор перемещения ), недавно добавлена ​​в стандартную библиотеку C ++ 0x.

Версия стандарта не влияет на искажение имен, хотя компиляторверсия делает, и более новые компиляторы необходимы для лучшей поддержки C ++ 0x, так что это может показаться связанным.

Возможно, вы используете слишком старую версию libstdc ++.

EDIT: Basicустранение неполадок:

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

Это действительно выглядит немного забавно.Определения для std::wstring (то есть std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >) выглядят правильно, узкие версии - нет.Имя std::string никогда не должно было дойти до стадии искажения, так как это просто определение типа.

Однако я получаю такой же вывод на 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> >&&)
...