Tengo un programa en C++ que compilo con mingw (gcc para Windows). Usando la versión TDM de mingw que incluye gcc 4.4.1. Los enlaces ejecutables a dos archivos de biblioteca estática (.a): uno de ellos es una biblioteca de terceros escrita en C; la otra es una biblioteca C++, escrita por mí, que utiliza la biblioteca C y proporciona mi propia API C++ en la parte superior.Definición múltiple de funciones en línea al vincular bibliotecas estáticas
Una parte (en mi opinión, excesiva) de la funcionalidad de la biblioteca C se implementa en funciones en línea. No puede evitar incluir las funciones en línea cuando usa la API de la biblioteca C, pero cuando trato de vincularlo todo, recibo errores de enlace que dicen que hay una definición múltiple de todas las funciones en línea, ambas que tengo llamado en mi biblioteca contenedora de C++ y los que no, básicamente todo lo definido en línea en los encabezados ha obtenido una función creada tanto en la biblioteca C como en la biblioteca C++.
No causa múltiples errores de definición cuando los archivos de inclusión se usan varias veces en diferentes archivos .c o .cpp en el mismo proyecto; el problema es solo que genera una definición por biblioteca.
¿Cómo/por qué el compilador genera funciones y símbolos para estas funciones en línea en ambas bibliotecas? ¿Cómo puedo obligarlo a dejar de generarlos en mi código? ¿Hay alguna herramienta que pueda ejecutar para quitar las funciones duplicadas del archivo .a, o una forma de hacer que el enlazador ignore múltiples definiciones?
(FYI, la biblioteca de terceros incluye guardias #ifdef __cplusplus y extern "C" en todos sus encabezados; de todos modos si ese fuera el problema, no causaría una definición múltiple de símbolo, causaría el problema opuesto porque el símbolo sería indefinido o al menos diferente).
Notablemente, los errores de enlace NO se producen si me enlace con la DLL de la biblioteca C de un tercero; sin embargo, luego recibo extraños errores de tiempo de ejecución que parecen tener que ver con mi código que tiene su propia versión de funciones que debería estar llamando desde la DLL. (Como si el compilador estuviera creando versiones locales de funciones que no solicité)
Se han formulado versiones similares de esta pregunta, sin embargo, no encontré la respuesta a mi situación en ninguna de estas:
la respuesta a esta pregunta fue que el cartel estaba definiendo las variables se multiplican , mi problema es múltiple definición de las funciones en línea: Repeated Multiple Definition Errors from including same header in multiple cpps
este fue un programa de MSVC, pero estoy utilizando MinGW; también, el problema del cartel en esta pregunta era la definición de un constructor de clase C++ fuera del cuerpo de clase en un encabezado, mientras que mi problema es con las funciones C en línea: Static Lib Multiple Definition Problem
Este tonto renombró todo su código C como C++ archivos y su código C no era C++ - segura: Multiple definition of lots of std:: functions when linking
Ésta fue sólo quieren saber por qué violar la regla de una definición no fue un error: unpredictable behavior of Inline functions with different definitions
en cuenta que C99 semántica en línea son diferentes a la de C++: En C , si una de las declaraciones de función en línea se especifica explícitamente como 'extern', crea una definición externa, que ya no es una definición en línea. Estas definiciones externas no pueden aparecer varias veces en el programa. En C++, un 'extern' explícito en dicha función no tiene ningún efecto. Lo mejor es hacer 'static inline' en C. –
Normalmente, las definiciones de funciones en línea están marcadas como símbolos 'débiles' y se supone que el enlazador elimina todos los duplicados. – Omnifarious
Gracias Johannes: utilizando definiciones de preprocesador, los archivos de cabecera de la biblioteca C declaran estas funciones "en línea" si están en los archivos .c de la biblioteca C y "inline en línea" cuando están en mi proyecto. Pero no estoy seguro de por qué lo hicieron de esa manera. La biblioteca C tiene algún código que usa la dirección de una función como valor clave único. Como programador de C++ veo eso como una mala práctica y realmente rezo por que no usaron la dirección de una función en línea de esa manera. Creo que hay casi suficiente información entre estos comentarios para poner en una respuesta, aunque todavía no puedo compilar el programa. – Dennis