Dans les langages de programmation C et C++, un #include guard, parfois appelé macro guard ou encore garde-fou, est une construction utilisée afin d'éviter le problème de la double inclusion pouvant apparaitre avec l'utilisation des directives d'inclusion. L'ajout de #include guards à un header permet de le rendre idempotent.

Double inclusion modifier

L'exemple de code C suivant démontre le problème de double inclusion pouvant arriver avec l'utilisation de la directive #include :

Fichier "grandpere.h" :
struct foo {
    int membre;
};
Fichier "pere.h" :
#include "grandpere.h"
Fichier "enfant.c" :
#include "grandpere.h"
#include "pere.h"

Le fichier "enfant.c" inclut directement et indirectement deux copies du texte contenu dans le header "grandpere.h". Lors de la compilation, cela produira une erreur puisque la structure foo sera en apparence définie deux fois.

Utilisation des #include guards modifier

Afin d'éviter la double inclusion du header "grandpere.h", il convient de lui ajouter des #include guards de la manière suivante :

Fichier "grandpere.h" :
#ifndef GRANDPERE_H_
#define GRANDPERE_H_
struct foo {
    int membre;
};
#endif  /* !GRANDPERE_H_ */

Les directives #ifndef et #endif sont dites de compilation conditionnelle. La directive #define définit une macro.

Ainsi, à la première inclusion du contenu de "grandpere.h" dans "enfant.c", la macro GRANDPERE_H sera créée. À la seconde insertion de "grandpere.h" dans "enfant.c", la macro GRANDPERE_H existera et donc la directive #ifndef renverra faux et le préprocesseur ne rajoutera pas le texte contenu entre la directive #ifndef et #endif. En conséquence, la structure <foo> ne sera définie qu'une seule fois.

Il existe plusieurs conventions de nom pour les macros de #include guards. Par exemple, il arrive de voir GRANDPERE_INCLUDED, _GRANDPERE_H ou __GRANDPERE_H.

Limitations et directive pragma modifier

Chaque macro de include guard doit avoir un nom unique qui lui est associé. Cela peut poser des problèmes dans les projets de taille importante.

C'est pourquoi dans certaines implémentations du C et C++, il existe une directive non-standard, #pragma_once qui gère les #include guards.

Voir aussi modifier