Guardias de inclusión #ifndef en C
-
Usar la guardia de inclusión
ifndef
para proteger contra la inclusión múltiple de archivos de cabecera en C -
Utilizar la directiva
ifndef
para asegurar que las macros no se definen varias veces en C
![Guardias de inclusión #ifndef en C](/img/C/feature-image---ifndef-in-c.webp)
Este artículo demostrará múltiples métodos de cómo usar #ifndef
include guards en C.
Usar la guardia de inclusión ifndef
para proteger contra la inclusión múltiple de archivos de cabecera en C
Los archivos de cabecera en C se utilizan para definir la interfaz para las funciones implementadas en el archivo fuente con el mismo nombre. La interfaz suele incluir prototipos de funciones, definiciones de estructuras de datos de acceso público y otras cosas diversas.
Tenga en cuenta que los archivos de cabecera pueden incluirse en el archivo fuente varias veces, lo que provoca errores de compilación. Normalmente, esto se evita con la directiva del preprocesador #ifndef
, que se llama wrapper #ifndef
. Cuando el contenido del fichero de cabecera está encerrado en la estructura mostrada en el siguiente ejemplo, donde la directiva #ifndef MY_GUARD
es el punto de partida y #endif
el final. La directiva #ifndef
comprueba si la macro MY_GUARD
está definida, si no lo está continúa y la define con la siguiente directiva. En caso de que el usuario incluya la misma cabecera por segunda vez, la directiva ifndef
evaluará false e ignorará el código anterior a la directiva #endif
. Como resultado, el compilador obtendrá sólo una copia del código de este fichero de cabecera y lo traducirá con éxito.
#include <stdio.h>
#ifndef MY_GUARD
#define MY_GUARD 1
#define PER(D) #D
#define JOIN(A, B) (A##B)
#define JOINX(A, B) JOIN(A, B)
int power(int base, int n) {
int p = base;
for (size_t i = 0; i < n; i++) {
p *= base;
}
return p;
}
#endif
Otro método para conseguir los mismos resultados es incluir la directiva #pragma once
en el fichero de cabecera. El preprocesador escanea esos ficheros de cabecera sólo una vez y garantiza que no se vuelvan a leer. Una desventaja del siguiente método es que tiene poca portabilidad a través de los diferentes preprocesadores, por lo que uno podría querer seguir con el método envolvente #ifndef
para asegurar una mejor flexibilidad del código base.
#include <stdio.h>
#pragma once
#define PER(D) #D
#define JOIN(A, B) (A##B)
#define JOINX(A, B) JOIN(A, B)
int power(int base, int n) {
int p = base;
for (size_t i = 0; i < n; i++) {
p *= base;
}
return p;
}
Utilizar la directiva ifndef
para asegurar que las macros no se definen varias veces en C
Alternativamente, podemos utilizar la directiva ifndef
para comprobar si la expresión de macro dada ya ha sido definida. La lógica funciona exactamente como en el ejemplo anterior; si la expresión no está definida, la siguiente directiva #define
se procesa en consecuencia. La única línea entre el #ifndef
y el #endif
es una definición de macro, lo que significa que en caso de que la condición sea falsa, sólo se salta la definición de la macro dada.
#include <stdio.h>
#include <stdlib.h>
#define PER(D) #D
#ifndef DLEVEL
#define DLEVEL 6
#endif
int main() {
for (int j = 0; j < DLEVEL; ++j) {
printf("%s\n", PER(stringify this));
}
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook