¿Qué hacen exactamente los guardias de C?

Tengo una pregunta con respecto a incluir guardias en C. He leído un poco, pero agradecería un poco de aclaración.

Digamos que tengo un archivo de encabezado “header.h” con una definición de función.

#ifndef HEADER_FILE #define HEADER_FILE int two(void){ return 2; } #endif 

Este archivo de cabecera tiene un protector de inclusión. Sin embargo, estoy un poco confundido en cuanto a lo que realmente está haciendo #define HEADER_FILE. Digamos que si olvidara el protector de inclusión, hubiera sido perfectamente legal que ignorara por completo agregar ‘#define HEADER_FILE’.

Entonces, mi pregunta: ¿Qué estamos haciendo exactamente cuando definimos HEADER_FILE? ¿Qué estamos definiendo? ¿Y por qué está bien olvidar la inclusión de la guarda en cuyo caso también podemos olvidar agregar #define HEADER_FILE?

Cualquier ayuda es apreciada!

Es una macro preprocesadora.

Todo esto es una syntax del preprocesador, que básicamente dice, si esta macro aún no se ha definido, #ifndef e incluya todo el código entre #ifndef y #endif

Lo que logra es evitar la inclusión del archivo más de una vez, lo que puede ocasionar problemas en su código.

Tu pregunta:

¿Y por qué está bien olvidar la inclusión de la guarda en cuyo caso también podemos olvidar agregar #define HEADER_FILE?

Está bien olvidarlo porque todavía es un código C legal sin él. El preprocesador procesa su archivo antes de comstackrlo e incluye el código especificado en su progtwig final si no hay una lógica que especifique por qué no debería hacerlo. Es simplemente una práctica común, pero no es obligatorio.

Un ejemplo simple podría ayudar a ilustrar cómo funciona esto:

Su archivo de encabezado, header_file.h diremos, contiene esto:

 #ifndef HEADER_FILE #define HEADER_FILE int two(void){ return 2; } #endif 

En otro archivo ( foo.c ), podría tener:

 #include "header_file.h" void foo() { int value = two(); printf("foo value=%d\n", value); } 

A lo que se traducirá esto una vez que esté “preprocesado” y listo para la comstackción es esto:

 int two(void){ return 2; } void foo() { int value = two(); printf("foo value=%d\n", value); } 

Todo lo que incluye la protección de inclusión aquí es determinar si los contenidos del encabezado entre #ifndef ... y #endif deben pegarse o no en lugar del #include original.

Sin embargo, dado que esa función no se declara extern o static , y en realidad se implementa en un archivo de cabecera, tendría un problema si intentara usarla en otro archivo de origen, ya que la definición de la función no se incluiría.

Evita que el archivo se incluya más de una vez, aquí

 #ifndef HEADER_FILE 

prueba si HEADER_FILE NO está definido, en caso de que sea cierto, entonces

 #define HEADER_FILE 

lo definiría, ahora si incluye el archivo en otro archivo, la primera vez que definirá HEADER_FILE , mientras que la segunda vez, ya estará definido y, por lo tanto, el contenido del archivo no se incluirá nuevamente, ya que el #ifndef HEADER_FILE ser falso

Recuerde que estos son evaluados por el preprocesador antes de que se realice la comstackción real, por lo que se evalúan en el momento de la comstackción.