c++ - ¿Se pueden enlazar diferentes dialectos GCC?
linker undefined-behavior (3)
Sé que en principio este es probablemente un comportamiento indefinido,
No es.
Supongamos que compilo una unidad de transición con
gcc -std=c++98
, y otra con-std=c++11
, usando exactamente la misma instalación del compilador. ¿Hay algún tipo de garantía de que pueda vincular los dos archivos de objetos y obtener un programa bien definido?
Sí, esto es compatible y funciona (hay excepciones, como habilitar el modo de depuración en un objeto y no en el otro, o usar opciones de cambio ABI explícitamente como -fshort-enums
en uno y no en el otro, pero eso debería ser obvio porque eso no funcionará incluso si usa la misma opción -std
para ambos objetos).
Por lo que puedo decir, los problemas potenciales solo pueden provenir de diferentes vistas de los encabezados de la biblioteca debido a las diferentes macros, y estos a su vez en el mejor de los casos agregarían nuevas funciones miembro, pero nunca objetos miembros, a las clases estándar de la biblioteca.
Derecha.
¿De alguna manera esto haría aceptable compilar diferentes partes de un proyecto más grande con diferentes opciones de dialecto de idioma?
Para GCC, sí, absolutamente. Como prueba de que está bien, considere que libstdc++.so
mismo contiene algunos objetos creados con -std=c++98
y algunos construidos con -std=c++14
.
Actualización: Debería agregar una pregunta ortogonal: ¿Qué sucede con el uso de dos versiones diferentes de GCC (por ejemplo, 4.3 y 4.6), pero cuál es la misma opción de dialecto (-std = c ++ 98)? El listado en esta documentación de GCC parece sugerir que la biblioteca es compatible en ambas direcciones entre 4.2.2 y 4.6.
No en ambas direcciones, necesitaría usar libstdc++.so
de GCC 4.6 (o más reciente), ya que el objeto compilado con esa versión podría depender de los símbolos que se introdujeron en la versión más reciente y no están presentes en la versión anterior de libstdc++.so
biblioteca.
Alguna información relacionada en https://stackoverflow.com/a/49119902/981959
Sé que en principio este es probablemente un comportamiento indefinido, pero en el interés de tratar con un proyecto grande, aquí está mi pregunta sobre GCC:
Supongamos que compilo una unidad de transición con gcc -std=c++98
, y otra con -std=c++11
, usando exactamente la misma instalación del compilador. ¿Hay algún tipo de garantía de que pueda vincular los dos archivos de objetos y obtener un programa bien definido?
Por lo que puedo decir, los problemas potenciales solo pueden provenir de diferentes vistas de los encabezados de la biblioteca debido a las diferentes macros, y estos a su vez en el mejor de los casos agregarían nuevas funciones miembro, pero nunca objetos miembros, a las clases estándar de la biblioteca.
¿De alguna manera esto haría aceptable compilar diferentes partes de un proyecto más grande con diferentes opciones de dialecto de idioma?
Actualización: Debería agregar una pregunta ortogonal: ¿Qué -std=c++98
con el uso de dos versiones diferentes de GCC (por ejemplo, 4.3 y 4.6), pero cuál es la misma opción de dialecto ( -std=c++98
)? El listado en esta documentación de GCC parece sugerir que la biblioteca es compatible en ambas direcciones entre 4.2.2 y 4.6.
A priori, no. La solución más segura es asumir que todas las opciones del compilador son idénticas, excepto cuando el compilador documenta específicamente que la opción no afecta la compatibilidad binaria. (Documentación que falta en la mayoría de los compiladores). En la práctica, en la falta de documentación, parece una apuesta segura que las opciones que controlan las advertencias ( -W...
in g ++) no afectarán la compatibilidad binaria, y que las opciones que Puede afectar la generación de código (nivel de idioma, etc.): g ++ generalmente mantiene la compatibilidad en diferentes niveles de optimización, donde VC ++ no lo hace.
Otro problema real es la definición de los símbolos del preprocesador en la línea de comandos. Una vez más, la apuesta más segura es que todas las definiciones son idénticas, pero también está de acuerdo, algo de sentido común está en orden: difícilmente se puede esperar que la biblioteca estándar haya sido compilada con los símbolos del preprocesador que se utilizan en su proyecto (cosas como MYPROG_CONFIG_FILE_LOCATION
, decir). Por otro lado, tenga en cuenta que las definiciones de preprocesador de _GLIBCXX_DEBUG
y _GLIBCXX_DEBUG_PEDANTIC
afectarán la compatibilidad binaria (aunque g ++ garantiza que obtendrá una versión de la biblioteca que funciona con ellas si las usa de manera consistente).
Con respecto a su pregunta: no esperaría mucho impacto en la compatibilidad binaria debido a la versión estándar, pero difícilmente me sorprendería si la elección afecta a algunos símbolos preprocesadores predefinidos, de una manera que rompería la compatibilidad binaria en la biblioteca. como si hubieras compilado algunos de los módulos con _GLIBCXX_DEBUG
, y algunos sin. Podría funcionar, pero no contaría con ello.
El lenguaje ABI es el mismo, pero STL ABI es diferente. Ver https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
Así que no recomiendo mezclar bibliotecas compiladas con -std = c ++ 98 -std = c ++ 11. Es posible que se bloquee al pasar datos a través de los límites de la imagen.
(Puede funcionar si solo llama a las funciones externas "C" y pasa solo los POD).
También ver relacionados: Mezclar diferentes estándares de C ++ con GCC