Inclure la garde
L' inclusion guard ou include Guardian est une technique de programmation en C et C ++ permettant de résoudre le problème de l'intégration multiple.
Ce problème se produit lorsque le même fichier d'en-tête est inclus plusieurs fois dans une unité de traduction . Ceci est généralement fait involontairement, par ex. B. si plusieurs modules utilisent la même bibliothèque .
Exemple d'intégration multiple
Les deux fichiers d'en-tête suivants A.het sont donnés B.h. une. définir une classe chacun :
// A.h
const int M = 123;
class A
{ /* ... */ };
// B.h
#include "A.h"
class B : public A
{ /* ... */ };
Dans le programme principal, les classes A et B doivent maintenant être utilisées:
1// program.cpp
2#include "A.h"
3#include "B.h"
4
5int main() { /* ... */ }
Le programme ne peut pas être compilé sans erreur car la classe A est définie deux fois: La première définition est faite lorsque le fichier d'en-tête est inclus A.hdans la ligne 2. La deuxième définition est faite parce que le fichier d'en-tête B.h, qui est inclus dans la ligne 3, lui-même A.himplique. La classe (et éventuellement d'autres variables) de ce fichier ont déjà été définies au préalable, ce qui conduit à une erreur de compilation.
Solution avec macros de préprocesseur (#ifndef)
Le wrapper #ifndef est l'approche traditionnelle et compatible C. Le problème de l'intégration multiple est résolu en définissant une macro de préprocesseur unique lorsque le fichier d'en-tête est inclus pour la première fois. Si la macro était déjà définie, les définitions suivantes de l'en-tête sont ignorées:
// A.h
#ifndef A_H
#define A_H
class A
{ /* ... */ };
#endif /* A_H */
Les commandes de préprocesseur ci-dessus provoquent la première incorporation de Ah (à partir de program.cpp ), la macro A_H n'est pas encore définie et le préprocesseur passe par les définitions. Avec la seconde intégration (à partir de Bh ) la macro est déjà définie et le préprocesseur saute le bloc # ifndef… #endif .
Puisque des macros existent dans l'espace de noms global, des problèmes peuvent survenir ici si une tentative est faite d'utiliser le même nom ailleurs (ce que l'on appelle la pollution de l'espace de noms ). Cela peut être évité en spécifiant des conventions de dénomination, mais cela ne résout pas le problème. Les identificateurs précédés d'un trait de soulignement (_) sont réservés aux définitions et définitions spécifiques au compilateur dans les bibliothèques standard. Un trait de soulignement en tête ne peut donc pas être utilisé dans le code de l'application selon les normes C et C ++ actuelles.
Le CPP , le préprocesseur du GCC , reconnaît automatiquement ces constructions, note les fichiers correspondants et les ignore lorsqu'ils sont à nouveau intégrés.
Solution via les extensions de langue (#pragma une fois)
La plupart des compilateurs C ++ utilisés aujourd'hui prennent en charge l'extension de langage #pragma once. Cela garantit également qu'un fichier (d'en-tête) n'est intégré qu'une seule fois, mais démarre à un niveau supérieur, directement au niveau du préprocesseur, et n'introduit pas de macros dans l'espace de noms global.
Pour l'utiliser, il suffit d' #pragma onceinsérer la directive préprocesseur dans le fichier d'en-tête :
// A.h
#pragma once
class A
{ /* ... */ };
Cette extension de langage est prise en charge par les implémentations C ++ suivantes:
- GCC ,
- Clang ,
- Microsoft Visual C ++ ,
- Compilateur Intel C ++ ,
- Comeau C / C ++ ,
- C ++ Builder XE3,
- Digital Mars C ++ .
Preuve individuelle
- ↑ WebLog d'Eric Fleegal ( page non disponible , recherche dans les archives web ) Info: Le lien a été automatiquement marqué comme défectueux. Veuillez vérifier le lien selon les instructions , puis supprimer cet avis. sur les blogs MSDN ; Récupéré le 19 août 2011.
- ↑ Norme C ++ (ISO / CEI 14882); Projet de travail C ++ N3242 (PDF), section 17.6.4.3.2
- ↑ norme C (ISO / CEI 9899); Projet de comité N1124 (PDF), sections 6.10.8 et 7.1.3 / 1.
- ↑ En -têtes uniques dans le manuel en ligne GNU CPP. Récupéré le 19 août 2011.
- ↑ Série de versions de GCC 3.4 - Modifications, nouvelles fonctionnalités et correctifs . Récupéré le 16 mai 2014.
- ↑ clang: Pragma.cpp Fichier source ( Memento de l' origine du 4 Avril, 2014 l' Internet Archive ) Info: L' archive lien a été inséré automatiquement et n'a pas encore été vérifiée. Veuillez vérifier le lien d'origine et d'archive conformément aux instructions , puis supprimer cet avis. . Récupéré le 16 mai 2014.
- ↑ MS Developer Network - une fois (C / C ++) . Récupéré le 16 mai 2014.
- ↑ Comeau C ++ 4.0 ( souvenir de l' original du 11 décembre 2013 dans les archives Internet ) Info: Le lien de l' archive a été automatiquement inséré et pas encore vérifié. Veuillez vérifier le lien d'origine et d'archive conformément aux instructions , puis supprimer cet avis. - Pré-version - Documentation utilisateur: Pragmas ( souvenir de l' original du 11 décembre 2013 dans les archives Internet ) Info: Le lien vers l' archive a été inséré automatiquement et n'a pas encore été vérifié. Veuillez vérifier le lien d'origine et d'archive conformément aux instructions , puis supprimer cet avis. . Récupéré le 16 mai 2014.
- ↑ #pragma une fois - RAD Studio XE3 . Récupéré le 16 mai 2014.
- ↑ Pragmas #pragma une fois . Récupéré le 16 mai 2014.