c++ - que - Beneficios de las bibliotecas de sólo encabezado
iostream dev c++ (4)
Beneficios de la biblioteca de sólo encabezado:
- Simplifica el proceso de construcción. No es necesario crear la biblioteca, y no es necesario especificar la biblioteca compilada durante el paso del enlace de la construcción. Si tiene una biblioteca compilada, es probable que desee compilar varias versiones de la misma: una compilada con la depuración habilitada, otra con la optimización habilitada y posiblemente otra copia de símbolos. Y quizás incluso más para un sistema multiplataforma.
Desventajas de una biblioteca de sólo encabezado:
Archivos de objetos más grandes. Cada método en línea de la biblioteca que se usa en algún archivo de origen también obtendrá un símbolo débil, definición fuera de línea en el archivo de objeto compilado para ese archivo de origen. Esto ralentiza el compilador y también ralentiza el enlazador. El compilador tiene que generar todo ese volumen, y luego el enlazador debe filtrarlo.
Una compilación más larga. Además del problema de hinchazón mencionado anteriormente, la compilación tomará más tiempo porque los encabezados son inherentemente más grandes con una biblioteca de solo encabezado que una biblioteca compilada. Los encabezados grandes necesitarán ser analizados para cada archivo fuente que use la biblioteca. Otro factor es que esos archivos de encabezado en una biblioteca de solo encabezado deben
#include
encabezados necesarios por las definiciones en línea, así como los encabezados que se necesitarían si la biblioteca se hubiera creado como una biblioteca compilada.Más compilación enredada. Usted obtiene muchas más dependencias con una biblioteca de solo encabezado debido a esos
#include
s adicionales necesarios con una biblioteca de solo encabezado. Cambie la implementación de alguna función clave en la biblioteca y es posible que necesite recompilar todo el proyecto. Realice ese cambio en el archivo de origen de una biblioteca compilada y todo lo que tiene que hacer es volver a compilar ese único archivo de origen de la biblioteca, actualizar la biblioteca compilada con ese nuevo archivo .o y volver a vincular la aplicación.Más difícil para el humano leer. Incluso con la mejor documentación, los usuarios de una biblioteca a menudo tienen que recurrir a la lectura de los encabezados de la biblioteca. Los encabezados en una biblioteca de solo encabezado están llenos de detalles de implementación que entorpecen la comprensión de la interfaz. Con una biblioteca compilada, todo lo que ve es la interfaz y un breve comentario sobre lo que hace la implementación, y eso suele ser todo lo que desea. Eso es realmente todo lo que deberías querer. No debería tener que conocer los detalles de la implementación para saber cómo usar la biblioteca.
¿Cuáles son los beneficios de una biblioteca de solo encabezado y por qué la escribiría de esa manera en contra de poner la implementación en un archivo separado?
El "beneficio" principal es que requiere que entregue el código fuente, por lo que terminará con informes de errores en las máquinas y con compiladores de los que nunca ha oído hablar. Cuando la biblioteca es completamente de plantillas, no tiene muchas opciones, pero cuando tiene la opción, solo el encabezado es generalmente una mala elección de ingeniería. (Por otro lado, por supuesto, el encabezado solo significa que no tiene que documentar ningún procedimiento de integración).
Hay situaciones en las que una única biblioteca de encabezado es la única opción, por ejemplo cuando se trata de plantillas.
Tener una biblioteca de solo encabezado también significa que no tiene que preocuparse por las diferentes plataformas donde se puede usar la biblioteca. Cuando separa la implementación, generalmente lo hace para ocultar los detalles de la implementación y distribuir la biblioteca como una combinación de encabezados y bibliotecas (archivos lib
, dll
o .so
). Por supuesto, estos deben compilarse para todos los diferentes sistemas operativos / versiones que ofrece soporte.
También podría distribuir los archivos de implementación, pero eso significaría un paso adicional para el usuario: compilar su biblioteca antes de usarla.
Por supuesto, esto se aplica caso por caso . Por ejemplo, las bibliotecas de sólo encabezado a veces aumentan tamaño del código y tiempos de compilación.
Sé que este es un hilo antiguo, pero nadie ha mencionado interfaces ABI o problemas específicos del compilador. Así que pensé que lo haría.
Básicamente, esto se basa en el concepto de que escribes una biblioteca con un encabezado para distribuir a las personas o que te reutilices contra todo en un encabezado. Si está pensando en reutilizar un encabezado y archivos de origen y compilarlos en cada proyecto, entonces esto no se aplica realmente.
Básicamente, si compila su código C ++ y construye una biblioteca con un compilador, el usuario intenta usar esa biblioteca con un compilador diferente o una versión diferente del mismo compilador, entonces puede obtener errores de vinculador o un comportamiento extraño en el tiempo de ejecución debido a la incompatibilidad binaria.
Por ejemplo, los proveedores de compiladores a menudo cambian su implementación de la STL entre versiones. Si tiene una función en una biblioteca que acepta un std :: vector, entonces se espera que los bytes en esa clase se ordenen de la forma en que se organizaron cuando se compiló la biblioteca. Si, en una nueva versión del compilador, el proveedor ha realizado mejoras de eficiencia en std :: vector, entonces el código del usuario ve la nueva clase que puede tener una estructura diferente y pasa esa nueva estructura a su biblioteca. Todo va cuesta abajo desde allí ... Por eso se recomienda no pasar objetos STL a través de los límites de la biblioteca. Lo mismo se aplica a los tipos C Run-Time (CRT).
Al hablar sobre el CRT, su biblioteca y el código fuente del usuario generalmente deben estar vinculados al mismo CRT. Con Visual Studio, si construye su biblioteca utilizando el CRT de multiproceso, pero el usuario se vincula con el CRT de depuración de multiproceso, entonces tendrá problemas de enlace porque es posible que su biblioteca no encuentre los símbolos que necesita. No puedo recordar qué función era, pero para Visual Studio 2015 Microsoft realizó una función CRT en línea. De repente, estaba en el encabezado, no en la biblioteca CRT, por lo que las bibliotecas que esperaban encontrarlo en el momento del enlace ya no podían hacerlo y esto generaba errores de enlace. El resultado fue que estas bibliotecas necesitaban recompilarse con Visual Studio 2015.
También puede obtener errores de enlace o un comportamiento extraño si utiliza la API de Windows pero crea con diferentes configuraciones de Unicode para el usuario de la biblioteca. Esto se debe a que la API de Windows tiene funciones que utilizan cadenas y macros / UnCIode o ASCII que define automáticamente los tipos correctos según la configuración de Unicode del proyecto. Si pasa una cadena a través del límite de la biblioteca que es del tipo incorrecto, entonces las cosas se rompen en tiempo de ejecución. O puede encontrar que el programa no se enlaza en primer lugar.
Estas cosas también son ciertas para pasar objetos / tipos a través de los límites de la biblioteca desde otras bibliotecas de terceros (por ejemplo, un vector Eigen o una matriz GSL). Si la biblioteca de terceros cambia su encabezado entre usted compilando su biblioteca y su usuario compilando su código, entonces las cosas se romperán.
Básicamente, para estar seguro, las únicas cosas que puede pasar a través de los límites de las bibliotecas son los tipos y los datos antiguos sin formato (POD). Idealmente, cualquier POD debería estar en estructuras que se definen en sus propios encabezados y no dependen de encabezados de terceros.
Si proporciona una biblioteca de solo encabezado, todo el código se compila con la misma configuración del compilador y contra los mismos encabezados, por lo que muchos de estos problemas desaparecen (siempre que la versión de las bibliotecas en parte que usted y su usuario sean compatibles con API).
Sin embargo, hay aspectos negativos que se han mencionado anteriormente, como el aumento del tiempo de compilación. También es posible que esté administrando una empresa, por lo que es posible que no desee entregar todos los detalles de la implementación del código fuente a todos sus usuarios en caso de que uno de ellos se los robe.