¿Necesito compilar los archivos de encabezado en un programa C?

5 minutos de lectura

avatar de usuario
yuliu

A veces veo a alguien compilar un programa en C como este:

gcc -o hello hello.c hello.h

Como sé, solo necesitamos poner los archivos de encabezado en el programa C como:

#include "somefile"

y compilar el programa en C: gcc -o hello hello.c.

¿Cuándo necesitamos compilar los archivos de encabezado o por qué?

  • Digamos que aún no ha escrito hola.c, pero tiene el archivo de encabezado. Luego puede usar “gcc hello.h” para verificar el archivo de encabezado en busca de errores de sintaxis. De lo contrario, tendría que crear un archivo fuente con una declaración de inclusión para hello.h (bueno… supongo que tendrá que hacerlo de todos modos en algún momento).

    – Marca

    28 de junio de 2016 a las 14:37

avatar de usuario
AnT apoya a Rusia

En primer lugar, en general:

Si estos .h son de hecho archivos de encabezado de estilo C típicos (a diferencia de ser algo completamente diferente que simplemente se nombra con .h extensión), entonces no, no hay razón para “compilar” estos archivos de encabezado de forma independiente. Los archivos de encabezado están destinados a incluirse en los archivos de implementación, no se envían al compilador como unidades de traducción independientes.

Dado que un archivo de encabezado típico generalmente contiene solo declaraciones que se pueden repetir de manera segura en cada unidad de traducción, se espera perfectamente que “compilar” un archivo de encabezado no tenga consecuencias perjudiciales. Pero al mismo tiempo no logrará nada útil.

Básicamente, compilar hello.h como una unidad de traducción independiente equivalente a crear un degenerado dummy.c archivo compuesto únicamente por #include "hello.h" directiva, y alimentando eso dummy.c archivo al compilador. Se compilará, pero no tendrá ningún propósito significativo.


En segundo lugar, específicamente para GCC:

Muchos compiladores tratarán los archivos de manera diferente según la extensión del nombre del archivo. GCC tiene un tratamiento especial para archivos con .h extensión cuando se proporcionan al compilador como argumentos de línea de comandos. En lugar de tratarlo como una unidad de traducción regular, GCC crea un encabezado precompilado archivo para eso .h expediente.

Usted puede leer sobre ello aquí: http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

Entonces, esta es la razón por la que podrías ver .h archivos que se envían directamente a GCC.

Bien, entendamos la diferencia entre código activo y pasivo.

El código activo es la implementación de funciones, procedimientos, métodos, es decir, las piezas de código que deben compilarse en código de máquina ejecutable. Lo almacenamos en archivos .c y seguro que necesitamos compilarlo.

El código pasivo no se está ejecutando en sí mismo, pero necesitaba explicar a los diferentes módulos cómo comunicarse entre sí. Por lo general, los archivos .h contienen solo prototipos (encabezados de funciones), estructuras.

Una excepción son las macros, que formalmente pueden contener piezas activas, pero debe comprender que se utilizan en una etapa muy temprana de construcción (preprocesamiento) con sustitución simple. En el momento de la compilación, las macros ya se sustituyen por su archivo .c.

Otra excepción son las plantillas de C++, que deben implementarse en archivos .h. Pero aquí está la historia similar a las macros: se sustituyen en la etapa inicial (instanciación) y formalmente, cada instancia es de otro tipo.

En conclusión, creo que si los módulos se formaron correctamente, nunca deberíamos compilar los archivos de encabezado.

avatar de usuario
edwin dólar

En algunos sistemas, los intentos de acelerar el ensamblaje de archivos ‘.c’ completamente resueltos llaman al preensamblado de archivos de inclusión “compilación de archivos de encabezado”. Sin embargo, es una técnica de optimización que no es necesaria para el desarrollo C real.

Dicha técnica básicamente calculó las declaraciones de inclusión y mantuvo un caché de las inclusiones aplanadas. Normalmente, la cadena de herramientas de C cortará y pegará recursivamente los archivos incluidos y luego pasará el elemento completo al compilador. Con un caché de encabezado precompilado, la cadena de herramientas verificará si alguna de las entradas (definiciones, encabezados, etc.) ha cambiado. De lo contrario, proporcionará los fragmentos de archivo de texto ya aplanados al compilador.

Dichos sistemas estaban destinados a acelerar el desarrollo; sin embargo, muchos de estos sistemas eran bastante frágiles. A medida que las computadoras se aceleraron y las técnicas de administración del código fuente cambiaron, en realidad se usan menos precompiladores de encabezado en el proyecto común.

Hasta que realmente necesite optimizar la compilación, le recomiendo que evite la precompilación de encabezados.

Cuando incluimos el archivo de encabezado como este: #include o #include “header.h”, entonces su preprocesador lo toma como entrada e incluye el archivo completo en el código fuente. el preprocesador reemplaza la directiva #include por el contenido del archivo especificado. Puede verificar esto mediante el indicador -E a GCC, que genera el archivo temporal .i (archivo de información) o puede usar el módulo cpp (LINUX) específicamente, que el controlador del compilador usa automáticamente cuando ejecutamos GCC. Entonces, en realidad se compilará junto con su código fuente, no es necesario compilarlo.

avatar de usuario
Cómo Chen

Creo que necesitamos preprocesar (tal vez NO llamar a la compilación) el archivo principal. Porque, según tengo entendido, durante la etapa de compilación, el archivo principal debe incluirse en el archivo c. Por ejemplo, en test.h tenemos

typedef enum{
    a,
    b,
    c
}test_t

y en test.c tenemos

void foo()
{
    test_t test;
    ...
}

durante la compilación, creo que el compilador colocará el código en el archivo principal y el archivo c juntos y el código en el archivo principal se procesará previamente y sustituirá el código en el archivo c. Mientras tanto, será mejor que definamos la ruta de inclusión en el archivo MAKE.

No necesita compilar archivos de encabezado. En realidad, no hace nada, por lo que no tiene sentido intentar ejecutarlo. Sin embargo, es una excelente manera de verificar errores tipográficos y errores, por lo que será más fácil más adelante.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad