Beneficios de las bibliotecas de encabezado único

¿Cuáles son los beneficios de una biblioteca de solo encabezado y por qué lo escribiría de esa manera para oponerse a poner la implementación en un archivo separado?

Hay situaciones en las que una biblioteca de solo 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 implementación y distribuir la biblioteca como una combinación de encabezados y bibliotecas (archivos lib , dll o .so ). Estos, por supuesto, tienen que comstackrse 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: comstackr su biblioteca antes de usarla.

Por supuesto, esto se aplica caso por caso . Por ejemplo, las bibliotecas de solo encabezado a veces aumentan código de tamaño y tiempos de comstackción.

Beneficios de la biblioteca de solo encabezado:

  • Simplifica el proceso de comstackción. No necesita construir la biblioteca, y no necesita especificar la biblioteca comstackda durante el paso de enlace de la comstackción. Si tiene una biblioteca comstackda, probablemente desee comstackr varias versiones de la misma: una comstackda con la depuración habilitada, otra con la optimización habilitada y posiblemente otra más sin símbolos. Y tal vez incluso más para un sistema multiplataforma.

Desventajas de una biblioteca de solo encabezado:

  • Archivos de objeto más grandes. Cada método en línea de la biblioteca que se utiliza en algún archivo fuente también obtendrá un símbolo débil, definición fuera de línea en el archivo de objeto comstackdo para ese archivo fuente. Esto ralentiza el comstackdor y también ralentiza el enlazador. El comstackdor debe generar todo ese engorro, y luego el enlazador debe filtrarlo.

  • Una comstackción más larga. Además del problema de hinchazón mencionado anteriormente, la comstackción llevará más tiempo porque los encabezados son intrínsecamente más grandes con una biblioteca de encabezado único que una biblioteca comstackda. Esos grandes encabezados van a tener que analizarse para cada archivo fuente que use la biblioteca. Otro factor es que esos archivos de encabezado en una biblioteca de solo cabecera tienen que #include encabezados necesarios para las definiciones en línea, así como también los encabezados que se necesitarían si la biblioteca se hubiera comstackdo como una biblioteca comstackda.

  • Comstackción más enredada. Obtiene muchas más dependencias con una biblioteca de solo encabezado debido a esos #include adicionales que se necesitan con una biblioteca de solo encabezado. Cambie la implementación de alguna función clave en la biblioteca y podría necesitar recomstackr todo el proyecto. Haga ese cambio en el archivo fuente de una biblioteca comstackda y todo lo que tiene que hacer es recomstackr ese archivo fuente de la biblioteca, actualizar la biblioteca comstackda 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 leer los encabezados de la biblioteca. Los encabezados de una biblioteca de solo encabezado están llenos de detalles de implementación que obstaculizan la comprensión de la interfaz. Con una biblioteca comstackda, todo lo que ve es la interfaz y un breve comentario sobre lo que hace la implementación, y eso es todo lo que quiere. Eso es todo lo que deberías querer. No debería tener que conocer los detalles de implementación para saber cómo usar la biblioteca.

El principal “beneficio” es que requiere que usted entregue el código fuente, por lo que terminará con informes de errores en máquinas y con comstackdores de los que nunca ha oído hablar. Cuando la biblioteca es completamente plantillas, no tiene muchas opciones, pero cuando tiene la opción, el encabezado solo suele ser una opción de ingeniería deficiente. (Por otro lado, por supuesto, el encabezado solo significa que no tiene que documentar ningún procedimiento de integración).

Sé que este es un hilo viejo, pero nadie ha mencionado interfaces ABI o problemas específicos del comstackdor. Entonces pensé que lo haría.

Esto se basa básicamente en el concepto de que usted está escribiendo una biblioteca con un encabezado para distribuir a las personas o reutilizar frente a tener todo en un encabezado. Si está pensando en reutilizar un encabezado y archivos de origen y volver a comstackrlos en cada proyecto, esto no se aplica realmente.

Básicamente, si comstack su código C ++ y construye una biblioteca con un comstackdor, entonces el usuario intenta usar esa biblioteca con un comstackdor diferente o una versión diferente del mismo comstackdor, entonces puede tener errores de enlazador o un extraño comportamiento de tiempo de ejecución debido a la incompatibilidad binaria.

Por ejemplo, los proveedores de comstackdores a menudo cambian su implementación del STL entre versiones. Si tiene una función en una biblioteca que acepta un std :: vector, espera que los bytes de esa clase se organicen de la forma en que se organizaron cuando se compiló la biblioteca. Si, en una nueva versión del comstackdor, el proveedor ha realizado mejoras de eficiencia en std :: vector, 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í … Es por eso que 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 con el mismo CRT. Con Visual Studio si construye su biblioteca utilizando el CRT multiproceso, pero el usuario establece un vínculo con el CRT multiproceso de depuración, entonces tendrá problemas de enlace porque es posible que su biblioteca no encuentre los símbolos que necesita. No recuerdo qué función era, pero para Visual Studio 2015 Microsoft hizo 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 generó errores de enlace. El resultado fue que estas bibliotecas necesitaban recomstackrse con Visual Studio 2015.

También puede obtener errores de enlace o un comportamiento extraño si usa 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 Unicode o ASCII y macros / define las cuales usan automágicamente los tipos correctos basados ​​en la configuración Unicode del proyecto. Si pasa una cadena a través del límite de la biblioteca que es el tipo incorrecto, las cosas se rompen en el tiempo de ejecución. O puede encontrar que el progtwig no se vincula en primer lugar.

Estas cosas también son válidas 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 que comstack su biblioteca y su usuario que comstack 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 la biblioteca son los tipos incorporados y los datos antiguos sin formato (POD). Idealmente, cualquier POD debería estar en estructuras definidas en sus propios encabezados y no depender de encabezados de terceros.

Si proporciona una biblioteca de solo encabezado, entonces todo el código se comstack con la misma configuración de comstackdor y con los mismos encabezados, de modo que muchos de estos problemas desaparecen (siempre que la versión de terceros, las bibliotecas parcialmente que usted y su usuario usan sean compatibles con API).

Sin embargo, hay aspectos negativos que se han mencionado anteriormente, como el aumento del tiempo de comstackción. Además, es posible que esté ejecutando un negocio, por lo que es posible que no desee entregar todos los detalles de implementación del código fuente a todos sus usuarios en caso de que alguno de ellos lo robe.