Referencia indefinida al operador nuevo

4 minutos de lectura

avatar de usuario
mbyrne215

Estoy tratando de construir un ejecutable de prueba de unidad simple, usando cpputest. Construí el marco cpputest en una biblioteca estática y ahora estoy tratando de vincularlo a un ejecutable. Sin embargo, estoy atado a una configuración de Makefile bastante complicada, debido al código relacionado.

Esta es mi línea de comando:

/usr/bin/qcc -V4.2.4,gcc_ntoarmle_acpp-ne -lang-c++ -O2 -g -g -o Application/UnitTests/Tests/symbols/UnitTestExe -Wl,--start-group Application/UnitTests/Tests/../.objs/main.o Application/UnitTests/lib/libcpputest.a -Wl,--end-group -lm 

Recibo muchos errores como los siguientes:

 Application/UnitTests/lib/libcpputest.a(CommandLineTestRunner.o): In function `CommandLineTestRunner::parseArguments(TestPlugin*)':
   Application/UnitTests/cpputest/src/CppUTest/.objs/../CommandLineTestRunner.cpp:114: undefined reference to `operator new(unsigned int, char const*, int)'

No puedo entender qué está causando esto. ¿No consigo operador nuevo gratis con C++?

  • Es muy difícil ayudar con esta información. Intentar reducir las condiciones necesarias para reproducir el problema. La línea de comando anterior es demasiado compleja, incluso si asumimos que el código es sencillo y no hace cosas como redefinir operator new.

    – Konrad Rodolfo

    17 de septiembre de 2010 a las 13:43


  • ¿El primer error informado es un nuevo error del operador? Si no, ¿cuál es el primer error informado?

    – Joel Rondeau

    17 de septiembre de 2010 a las 13:50

  • Sí, los únicos errores informados son errores nuevos del operador. El que se muestra es el primero.

    – mbyrne215

    17 de septiembre de 2010 a las 13:50

  • Los casos en los que veo un error de referencia indefinido, generalmente significan enlaces incorrectos y rutas adecuadas no proporcionadas donde están instaladas las bibliotecas.

    – Codificador tonto

    17 de septiembre de 2010 a las 13:54

  • Editado para eliminar elementos innecesarios de la línea de comandos.

    – mbyrne215

    17 de septiembre de 2010 a las 13:55

avatar de usuario
zvrba

Probablemente necesite vincular con la biblioteca de tiempo de ejecución de soporte de C ++. Esto sucede automáticamente cuando invocas a g++. En Linux, esto se logra agregando el -lstdc++ marca al enlazador. Tienes que descubrir cómo hacer lo mismo en tu plataforma.

Tal vez estás llamando gccel compilador de C en lugar de g++que es el compilador de C++.

  • Exactamente esta respuesta de una sola línea señaló mi falla, en la que corro hoy.

    – usuario5329483

    27 ago a las 18:33


avatar de usuario
sbi

Hay muy poca información en su pregunta para trabajar, pero parece que algún código usa alguna forma de colocación nuevay aunque ese especial operator new es declarado (el compilador lo encuentra y compila el código usándolo), el enlazador no puede encontrar su definición.

(Dado que esta antigua respuesta mía parece aún llamar la atención: consulte aquí para obtener una discusión extensa sobre la declaración frente a la definición).

  • No estoy seguro de qué otra información agregar. El código es realmente simple; no redefine ‘nuevo’, por lo que no puedo entender por qué el enlazador no puede encontrarlo en la biblioteca estándar.

    – mbyrne215

    17 de septiembre de 2010 a las 14:02

  • @mbyrne215: podría agregar el código más simple que reproduzca esto. El mensaje de error menciona claramente un operator new(unsigned int, char const*, int) (llamado desde CommandLineTestRunner::parseArguments(TestPlugin*)), que claramente no es la versión estándar de ese operador.

    – sbi

    17 de septiembre de 2010 a las 14:07


  • Estás bien; Me obsesioné tanto buscando por qué las bibliotecas estándar no funcionaban, que no revisé de cerca la biblioteca de terceros. Secretamente estaba redefiniendo lo nuevo. Quité esa parte y todo bien. Gracias.

    – mbyrne215

    17 de septiembre de 2010 a las 14:21

Debe reconstruir su código desde cero, incluida la biblioteca. Recibí este error porque sin darme cuenta copié archivos de objetos compilados en otra máquina (con el resto de la fuente) a mi máquina. Lo más probable es que esto perturbe el paso de vinculación, ya que ahora hay dos tipos de archivos de objetos, nativos (para archivos de origen modificados) y no nativos (todos los demás). Supongo que aquí, pero el operador ‘nuevo’ significa cosas ligeramente diferentes en diferentes arquitecturas y es por eso que recibe este error.

PD Sé que es demasiado tarde para una respuesta útil, pero todavía estoy publicando esto para que conste.

Para QNX 6.5.0 he especificado el indicador -lang-c++ por qcc (gcc) para evitar el error.

avatar de usuario
frecuente

Al igual que la publicación original, en mi caso, este error ocurrió al intentar vincular un software usando el marco CppUTest.

En mi caso, el origen del problema parece estar relacionado con el hecho de que deshabilité la opción de compilación MEMORY_LEAK_DETECTION de CppUTest. Lo habilité de nuevo, lo que resolvió el problema.

avatar de usuario
Stepan Yakovenko

A veces agregando -lstdc++ no es suficiente. Debes agregarlo en el lugar correcto. Por ejemplo, tenía una lista como esta, que no funcionaba:

target_link_libraries(cfr2 pthread m stdc++ "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" )

Pero este funciona bien:

target_link_libraries(cfr2 pthread m "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" stdc++)

Sería genial si alguien lo explicara en la sección de comentarios.

  • stackoverflow.com/a/409402/983556

    – David Carpintero

    26 ago a las 21:30

¿Ha sido útil esta solución?