¿Dónde poner las instrucciones include, header o source?


¿Debo poner los includes en el archivo de cabecera o en el archivo fuente? Si el archivo de encabezado contiene las instrucciones include, entonces si incluyo ese archivo de encabezado en mi fuente, ¿mi archivo de origen tendrá todos los archivos incluidos que estaban en mi cabecera? ¿O debería incluirlos solo en mi archivo fuente?

Author: Paul Roub, 2010-10-15

9 answers

Solo ponga includes en un encabezado si el encabezado mismo los necesita.

Ejemplos:

  • Su función devuelve el tipo size_t. Luego #include <stddef.h>en el archivo header.
  • Tu función usa strlen. Luego #include <string.h>en el archivo fuente.
 105
Author: schot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 15:01:12

Ha habido bastante desacuerdo sobre esto a lo largo de los años. En un momento, era tradicional que un encabezado solo declare lo que estaba en cualquier módulo con el que estuviera relacionado, por lo que muchos encabezados tenían requisitos específicos que #include un cierto conjunto de encabezados (en un orden específico). Algunos programadores de C extremadamente tradicionales siguen este modelo (religiosamente, al menos en algunos casos).

Más recientemente, hay un movimiento hacia hacer que la mayoría de los encabezados sean independientes. Si ese encabezado requiere algo más, el encabezado mismo se encarga de eso, asegurando que todo lo que necesita esté incluido (en el orden correcto, si hay problemas de pedido). Personalmente, prefiero esto especially especialmente cuando el orden de los encabezados puede ser importante, resuelve el problema una vez, en lugar de requerir a todos los que lo usan para resolver el problema una vez más.

Tenga en cuenta que la mayoría de los encabezados solo deben contener declaraciones. Esto significa que agregar un encabezado innecesario no debería (normalmente) tener ningún efecto en su ejecutable final. Lo peor que sucede es que ralentiza un poco la compilación.

 23
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:58:08

Sus #include s deben ser de archivos de encabezado, y cada archivo (fuente o encabezado) debe #include los archivos de encabezado que necesita. Los archivos de encabezado deben #include los archivos de encabezado mínimos necesarios, y los archivos de origen también deben, aunque no es tan importante para los archivos de origen.

El archivo fuente tendrá las cabeceras it #includes, y las cabeceras they #include, y así sucesivamente hasta la máxima profundidad de anidamiento. Esta es la razón por la que no desea #includesuperfluos en los archivos de encabezado: pueden hacer que un archivo de origen incluya muchos de los archivos de encabezado que puede no necesitar, ralentizando la compilación.

Esto significa que es completamente posible que los archivos de encabezado se incluyan dos veces, y eso puede ser un problema. El método tradicional es poner "include guards" en los archivos de cabecera, como este para file foo.h:

#ifndef INCLUDE_FOO_H
#define INCLUDE_FOO_H
/* everything in header goes here */
#endif
 10
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:56:57

Si el archivo de cabecera A #includes los archivos de cabecera B y C, entonces cada archivo fuente que #includes A también obtendrá B y C #included. El preprocesador literalmente solo realiza la sustitución de texto: en cualquier lugar que encuentre texto que diga #include <foo.h> lo reemplaza con el texto del archivo foo.h.

Hay diferentes opiniones sobre si debe poner #includes en encabezados o archivos fuente. Personalmente, prefiero poner todo #includes en el archivo fuente por defecto, pero cualquier archivo de encabezado que no pueda compilar sin otro requisito previo los encabezados deben #include esos encabezados en sí.

Y cada archivo de cabecera debe contener un protector include para evitar que se incluya varias veces.

 4
Author: Vicky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:55:39

En algunos entornos, la compilación será más rápida si solo se incluyen los archivos de cabecera que se necesitan. En otros entornos, la compilación se optimizará si todos los archivos de origen pueden usar la misma colección primaria de encabezados (algunos archivos pueden tener encabezados adicionales más allá del subconjunto común). Idealmente, las cabeceras deben ser construidas para que múltiples operaciones # include no tengan efecto. Sin embargo, puede ser bueno rodear las sentencias #include con comprobaciones de la protección include del archivo que se incluirá eso crea una dependencia sobre el formato de ese guardia. Además, dependiendo del comportamiento de almacenamiento en caché de archivos de un sistema, un #include innecesario cuyo objetivo termina siendo # ifdef'ed completamente alejado puede no tomar mucho tiempo.

Otra cosa a considerar es que si una función toma un puntero a una estructura, uno puede escribir el prototipo como

void foo(struct BAR_s *bar);

Sin una definición para BAR_s que tenga que estar en el alcance. Un enfoque muy práctico para evitar inclusiones innecesarias.

PS many en muchos de mis proyectos, habrá un archivo que se espera que cada módulo incluya, conteniendo cosas como typedefs para tamaños enteros y algunas estructuras y uniones comunes[e. g.

typedef union {
  unsigned long l;
  unsigned short lw[2];
  unsigned char lb[4];
} U_QUAD;

(Sí, sé que estaría en problemas si me mudara a una arquitectura big-endian, pero como mi compilador no permite estructuras anónimas en uniones, usar identificadores con nombre para los bytes dentro de la unión requeriría que se accediera a ellos como theUnion.b. b1, etc. lo que parece bastante molesto.

 4
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 15:55:19

Haga que todos sus archivos se puedan construir usando solo lo que incluyen. Si no necesitas un include en tu encabezado, elimínalo. En un gran proyecto, si no mantiene esta disciplina, se deja abierto a romper una compilación completa cuando alguien elimina una inclusión de un archivo de encabezado que está siendo utilizado por un consumidor de ese archivo y ni siquiera por el encabezado.

 3
Author: rerun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:59:24

El enfoque en el que he evolucionado durante más de veinte años es este;

Considere una biblioteca.

Hay varios archivos C, un archivo H interno y un archivo H externo. Los archivos C incluyen el archivo H interno. El archivo H interno incluye el archivo H externo.

Se ve que desde los compiladores POV, ya que compila un archivo C, hay una jerarquía;

External - > internal - > C code

Este es el orden correcto, ya que lo que es externo es todo un un tercero necesita usar la biblioteca. Lo que es interno se requiere para compilar el código C.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 15:01:16

Su archivo fuente tendrá las instrucciones include si lo coloca en el encabezado. Sin embargo, en algunos casos sería mejor ponerlos en el archivo fuente.

Recuerde que si incluye esa cabecera en cualquier otra fuente, también obtendrán las inclusiones de la cabecera, y eso no siempre es deseable. Solo debes incluir cosas donde se usan.

 1
Author: Splashdust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:54:30

Solo debe incluir archivos en su encabezado que necesite declarar constantes y declaraciones de funciones. Técnicamente, estas inclusiones también se incluirán en su archivo de origen, pero para mayor claridad, solo debe incluir en cada archivo los archivos que realmente necesita usar. También debe protegerlos en su encabezado de inclusión múltiple de esta manera:

#ifndef NAME_OF_HEADER_H
#define NAME_OF_HEADER_H

...definition of header file...

#endif

Esto evita que el encabezado se incluya varias veces, lo que resulta en un error del compilador.

 1
Author: JRam930,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-15 14:59:12