Una de mis principales quejas sobre C ++ es lo difícil que es en la práctica pasar los objetos de la biblioteca estándar fuera de los límites de la biblioteca dinámica (es decir, dll / so).
La biblioteca estándar a menudo es solo de encabezado. Lo cual es genial para hacer algunas optimizaciones increíbles. Sin embargo, para los dll, a menudo se crean con diferentes configuraciones de compilador que pueden afectar la estructura / código interno de los contenedores de una biblioteca estándar. Por ejemplo, en MSVC, un dll puede compilarse con la depuración del iterador activada mientras que otro construye con él desactivado. Estos dos dlls pueden tener problemas para pasar contenedores estándar. Si expongo std::string
en mi interfaz, no puedo garantizar que el código que utiliza el cliente std::string
coincida exactamente con el de mi biblioteca std::string
.
Esto lleva a problemas difíciles de depurar, dolores de cabeza, etc. Usted controla rígidamente la configuración del compilador en su organización para evitar estos problemas o utiliza una interfaz C más simple que no tendrá estos problemas. O especifique a sus clientes la configuración esperada del compilador que deberían usar (lo que apesta si otra biblioteca especifica otras configuraciones del compilador).
Mi pregunta es si C ++ 11 intentó hacer algo para resolver estos problemas.
DLL
s. EntreSO
s siempre funcionó bien.Respuestas:
Tiene razón en que cualquier cosa STL, en realidad, cualquier cosa de cualquier biblioteca de terceros que tenga plantillas, es mejor evitarla en cualquier API pública de C ++. También desea seguir la larga lista de reglas en http://www.ros.org/reps/rep-0009.html#definition para inhibir la rotura de ABI, lo que hace que la programación de API públicas de C ++ sea una tarea difícil.
Y la respuesta con respecto a C ++ 11 es no, este estándar no toca eso. Más interesante es por qué no? La respuesta es porque C ++ 17 es muy conmovedor, y para que se implementen los módulos C ++ necesitamos plantillas exportadas para trabajar, y para eso necesitamos un compilador de tipo LLVM como clang que puede volcar el AST completo en el disco y luego realice búsquedas dependientes de la persona que llama para manejar los muchos casos de violación de ODR en cualquier proyecto grande de C ++, que, por cierto, incluye muchos códigos GCC y ELF.
Por último, veo muchos comentarios de odio de MSVC y pro-GCC. Estos están muy mal informados: GCC en ELF es fundamental e irremediablemente incapaz de producir un código C ++ válido y correcto. Las razones para esto son muchas y muchas, pero citaré rápidamente un ejemplo de caso: GCC en ELF no puede producir con seguridad extensiones de Python escritas usando Boost.Python donde más de una extensión basada en Boost.Python se carga en Python. Esto se debe a que ELF con su tabla de símbolos C global es simplemente incapaz por el diseño de prevenir violaciones de ODR que causan segfaults, mientras que PE y MachO y, de hecho, la especificación de los módulos C ++ propuestos usan tablas de símbolos por módulo, lo que por cierto también significa tiempos de inicio de proceso mucho más rápidos. Y hay muchos más problemas: vea un StackOverflow al que respondí recientemente enhttps://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055, por ejemplo, cuando los lanzamientos de excepciones de C ++ se rompen irremediablemente en ELF.
Último punto: con respecto a la interoperabilidad de diferentes STL, este es un gran dolor para muchos usuarios corporativos grandes que intentan mezclar bibliotecas de terceros que están estrechamente integradas a alguna implementación de STL. La única solución es un nuevo mecanismo para que C ++ maneje la interoperabilidad STL, y mientras lo hacen, también podría corregir la interoperabilidad del compilador para que pueda (por ejemplo) mezclar archivos de objetos compilados MSVC, GCC y clang y todo funciona . Vería el esfuerzo de C ++ 17 y vería qué sucede allí en los próximos años; me sorprendería si nada sucede.
fuente
La especificación nunca tuvo este problema. Esto se debe a que tiene un concepto llamado "regla de una definición", que exige que cada símbolo tenga exactamente una definición en el proceso de ejecución.
Las DLL de Windows violan este requisito. Por eso hay todos estos problemas. Por lo tanto, depende de Microsoft solucionarlo, no el comité de estandarización de C ++. Unix nunca tuvo este problema, porque las bibliotecas compartidas funcionan de manera diferente allí y, de manera predeterminada, se ajustan a una regla de definición (puede romperlo explícitamente, pero obviamente solo lo hace si sabe que puede pagarlo y necesita exprimir los pocos ciclos adicionales).
Las DLL de Windows violan una regla de definición porque:
Unix que utiliza las exportaciones en formato ELF importa implícitamente todos los símbolos exportados para evitar el primer problema y no distingue entre símbolos resueltos estáticamente y dinámicamente hasta el momento del enlace estático para evitar el segundo.
El otro problema es de las banderas del compilador. Ese problema existe para cualquier programa compuesto de múltiples unidades de compilación, las bibliotecas dinámicas no tienen que estar involucradas. Sin embargo, es mucho peor en Windows. En Unix, realmente no importa si se vincula estática o dinámicamente, de todos modos nadie vincula el tiempo de ejecución estándar estáticamente (en Linux incluso podría ser ilegal) y no hay un tiempo de ejecución de depuración especial, por lo que una compilación es lo suficientemente buena. Pero la forma en que Microsoft implementó la vinculación estática y dinámica, el tiempo de ejecución de depuración y liberación y algunas otras opciones significa que causaron una explosión combinatoria de las variantes de biblioteca necesarias. De nuevo un problema de plataforma en lugar de un problema de lenguaje C ++.
fuente
No.
Se está trabajando mucho para reemplazar el sistema de encabezado, característica que se llama Módulos y que podría tener un impacto en esto, pero ciertamente no es grande.
fuente