2011-01-26 5 views
6

Estoy compilando un proyecto usando Cygwin (GCC v4.5.0) y estoy teniendo un problema de enlazador impar. Espero que alguien con cierta experiencia pueda ayudar.Vinculación de la biblioteca estándar de C++ con diferentes estándares de C++

Error: undefined reference to std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)

Sin embargo, el enlace sólo falla cuando compilo con la bandera compilador gcc: -std=c++0x Tiene éxito cuando no se especifica el estándar.

Algunas notas:

  1. me informo gcc para enlazar la librería estándar de forma manual con la bandera del compilador: -lstdc++
  2. La dependencia símbolo es originario de un archivo de cabecera de la biblioteca Boost (v.1.45.0) : boost::units::detail::utility.hpp, function: std::string demangle(const char* name);
  3. La aplicación compila y enlaza correctamente utilizando MinGW gcc v4.5.0.

Preguntas:

  1. ¿La biblioteca estándar compilado por lo general contienen símbolos diferentes para diferentes estándares de C++?
  2. ¿El cambio de nombre de símbolos cambia con diferentes estándares de C++ en GCC?
  3. ¿Por qué el enlazador no puede encontrar los símbolos para std::basic_string cuando puedo garantizar que puede encontrar libstdc++.a?

Gracias de antemano a todos.

-jt

+0

Hay algo mal con su texto de error. ¿Lo citaron directamente? No tiene ningún sentido. –

+0

@Noah: ¿Te refieres al "&&"? Parece una notación de referencia de valor de C++ 0x. –

Respuesta

8

Sí, las dos nuevas revisiones de los informes técnicos estándar y crea muchos cambios en el contenido de la biblioteca estándar. La función a la que hizo referencia (std::stringmovimiento constructor) se acaba de agregar en la biblioteca estándar de C++ 0x.

La versión de la norma no afecta al cambio de nombre, aunque sí la versión del compilador, y se necesitan compiladores más nuevos para una mejor compatibilidad con C++ 0x, por lo que podría parecer relacionada.

Probablemente esté utilizando una versión demasiado antigua de libstdC++.

EDIT: Solución de problemas básicos:

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

Esto sí que parece un poco raro. Las definiciones para std::wstring (es decir, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >) parecen correctas, las versiones angostas no. El nombre std::string no debería haber sobrevivido a la etapa de destrucción, ya que es solo un typedef.

Sin embargo, me da la misma salida en 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> >&&) 
+0

Hmm ... ¿así que eso indicaría que quizás la versión de cygwin de GCC v.4.5.0 es defectuosa? –

+1

Cuando instaló la versión experimental de g ++, ¿también obtuvo v4.5 de 'libstdC++ 6-devel'? Acabo de agregar a mi respuesta los comandos necesarios para verificar esa versión. –

+1

Ahh que lo arregla. Muchas gracias Ben. No había instalado libstdC++ 6-devel. Es lamentable que cygwin no proporcione más documentación para que el proceso sea menos propenso a errores. –

Cuestiones relacionadas