La plupart des fichiers d'en-tête enveloppent leur contenu comme tel:
#ifndef MY_HEADER_H #define MY_HEADER_H // header body... #endif MY_HEADER_H
Si cela était supprimé, cela poserait-il des problèmes lors de l'inclusion du fichier d'en-tête dans plusieurs fichiers source? ou le préprocesseur est-il assez intelligent pour l'ignorer? (Je sais que cela pose des problèmes lorsqu'il est inclus plusieurs fois dans le même fichier source)
3 Réponses :
Si cela était supprimé, cela poserait-il des problèmes lors de l'inclusion du fichier d'en-tête dans plusieurs fichiers sources?
Non. Cela peut entraîner des problèmes lors de l'inclusion du fichier d'en-tête dans le même fichier source plusieurs fois.
ou le préprocesseur est-il assez intelligent pour l'ignorer?
Non. Le préprocesseur ne connaît pas plus d'un fichier source à la fois.
mais si a.cc et b.cc ont tous deux ce fichier d'en-tête et alors je le compile avec gcc a.cc b.cc , enroulé Le même fichier d'en-tête n'est-il pas copié dans les deux fichiers?
@rici: Donc, "oui" (dans cette première étape, pré-liaison)
@Joe Oui, il sera copié dans les deux fichiers. Et ces fichiers sont des fichiers séparés donc il n'y a pas de problème.
Si cela était supprimé, cela poserait-il des problèmes lors de l'inclusion du fichier d'en-tête ...
Potentiellement, oui. Pas nécessairement. En général, cela dépend. En particulier, cela dépend du contenu de l'en-tête et si l'en-tête est inclus plus d'une fois dans une seule unité de traduction (TU). Certaines déclarations peuvent être répétées, d'autres non. Par exemple, les définitions ne doivent pas être répétées.
... dans plusieurs fichiers source?
Le fait que l'en-tête ait une macro de garde n'a pas d'importance pour l'en-tête étant inclus dans plusieurs TU. Chaque TU est prétraité séparément et la garde n'empêche pas l'inclusion dans plusieurs TU.
Si un en-tête contient des définitions qui peuvent ne pas être incluses dans plus d'un TU (comme la définition d'une fonction non en ligne), alors l'en-tête n'est généralement pas très utile (bien qu'un exemple pratique de cela existe: un en-tête -seules les bibliothèques fournissent un moyen d'inclure leur propre définition de fonction main ).
Comment le préprocesseur saurait-il que l'ignorer est la bonne chose à faire? Par exemple, considérons le fichier d'en-tête suivant, "foobar.h":
int main()
{
#define FOO printf
#define BAR "hello"
#include "foobar.h"
#undef BAR
#define BAR " world\n"
#include "foobar.h"
}
Et le code C suivant:
FOO(BAR);
Ici, en ignorant la seconde tentative d'inclure le fichier briserait le comportement du programme.
Donc, puisque le compilateur ne peut pas savoir que l'ignorer est la bonne chose à faire, il ne peut pas l'ignorer. Donc, si vous voulez qu'il l'ignore, vous devrez le dire.
Celles-ci sont appelées incluent les gardes et puisque C et C ++ proviennent de périodes où le temps processeur était plus précieux que temps du programmeur, il vaut mieux les utiliser
Lecture supplémentaire: Comment fonctionne le processus de compilation / liaison?