Si j'ai une variable qui peut être utilisée dans plusieurs sources - est-ce une bonne pratique de la déclarer dans un en-tête? ou vaut-il mieux le déclarer dans un .c
fichier et utiliser extern
dans d'autres fichiers?
Vous devez déclarer la variable dans un fichier d'en-tête:
extern int x;
puis définir dans n fichier C:
int x;
En C, la différence entre une définition et une déclaration est que la définition réserve de l'espace pour la variable, tandis que la déclaration introduit simplement la variable dans la table des symboles (et obligera l'éditeur de liens à aller la chercher quand il s'agit de lier l'heure) .
Vous pouvez (devez) le déclarer comme extern
dans un fichier d'en-tête et le définir dans exactement 1 fichier .c.
Notez que ce fichier .c doit également utiliser l'en-tête et que le modèle standard ressemble à:
// file.h
extern int x; // declaration
// file.c
#include "file.h"
int x = 1; // definition and re-declaration
Si vous le déclarez comme
int x;
dans un fichier d'en-tête qui est ensuite inclus à plusieurs endroits, vous vous retrouverez avec plusieurs instances de x (et potentiellement des problèmes de compilation ou de liaison).
La bonne façon d'aborder cela est de dire au fichier d'en-tête
extern int x; /* declared in foo.c */
puis dans foo.c vous pouvez dire
int x; /* exported in foo.h */
Ensuite, vous pouvez inclure votre fichier d'en-tête dans autant d'endroits que vous le souhaitez.
L'essentiel est de conserver les déclarations de la variable dans le fichier d'en-tête et le fichier source.
J'utilise cette astuce
------sample.c------
#define sample_c
#include sample.h
(rest of sample .c)
------sample.h------
#ifdef sample_c
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int x;
Sample.c n'est compilé qu'une seule fois et définit les variables. Tout fichier qui inclut sample.h ne reçoit que le "extern" de la variable; il alloue de l'espace pour cette variable.
Lorsque vous changez le type de x, cela change pour tout le monde. Vous n'aurez pas besoin de vous souvenir de le changer dans le fichier source et le fichier d'en-tête.