8
votes

Le mot clé externe est-il vraiment nécessaire?

...
#include "test1.h"

int main(..)
{
    count << aaa <<endl;
}
aaa is defined in test1.h,and I didn't use extern keyword,but still can reference aaa.So I doubt is extern really necessary?

1 commentaires

Vous devez également fournir le contenu de Test1.h aussi. Il est possible que vous utilisiez la mauvaise terminologie pour décrire ce qui est dans Test1.h.


5 Réponses :


2
votes

Si AAA n'est pas défini dans une autre unité de compilation, vous n'avez pas besoin d'externe, sinon vous le faites.


0 commentaires

5
votes

Si votre test1.h a la définition de AAA et que vous vouliez inclure le fichier d'en-tête dans plusieurs unités de traduction, vous passerez dans plusieurs erreurs de définition, sauf si AAA n'est pas constante. Mieux vous définissez l'AAA dans un fichier CPP et ajoutez une définition externe dans un fichier d'en-tête pouvant être ajouté à d'autres fichiers comme en-tête.

règle de pouce pour avoir une variable et constante dans le fichier d'en-tête xxx

Etant donné que constante présente une liaison interne en C ++ Toute constante définie dans une unité de traduction ne sera pas visible à une autre unité de traduction, mais ce n'est pas le cas pour variable, ils ont une liaison externe, c'est-à-dire visible par une autre unité de traduction . Mettre la définition d'une variable dans un en-tête, partagé dans une autre unité de traduction entraînerait une définition multiple d'une variable, entraînant une erreur de définition multiple.


0 commentaires

4
votes

Dans ce cas, extern n'est pas nécessaire. Externe est nécessaire lorsque le symbole est déclaré dans une autre unité de compilation.

Lorsque vous utilisez la directive de prétraitement #include , le fichier fourni est copié à la place de la directive. Dans ce cas, vous n'avez pas besoin extern parce que le compilateur connaît déjà aaa .


1 commentaires

@httpinterpret Chaque fichier CPP avec tous les en-têtes fournis formera une unité de compilation CPPFile ==. Les fichiers d'en-tête ne sont qu'un mécanisme permettant de réduire la dactylographie, d'examiner votre projet en tant que groupe de fichiers du CPP comprenant "Header.h" remplacé par le contenu réel du fichier d'en-tête. L'unité de compilation n'est que des fichiers d'objet qui voient après la compilation, reliant tous ces fichiers vous donnera l'EXE / DLL.



7
votes

J'ai trouvé le meilleur moyen d'organiser vos données consiste à suivre deux règles simples:

  • Ne déclarez que des choses dans les fichiers d'en-tête. LI>
  • Définissez les choses en C (ou CPP, mais je vais simplement utiliser C ici pour la simplicité) Fichiers. Li> ul>

    par déclarer, je veux dire informer le compilateur que les choses existent, mais n'allouez pas de stockage pour eux. Ceci inclut typedef code>, struct code>, extern code> et ainsi de suite. P>

    par définir, je généralement em > signifie "allouer de l'espace pour", comme int code> et ainsi de suite. p>

    Si vous avez une ligne comme: P>

    extern int aaa;
    


10 commentaires

Pouvez-vous élaborer le cas que vous avez mentionné que "Si vous liez deux fichiers d'objets ensemble, avoir le même symbole défini"? Comment fonctionner const corriger le problème? -


extern int AAA; n'est pas une définition. C'est une déclaration. De plus, struct foo {int j}; est une définition qui est évidemment acceptable dans les fichiers d'en-tête. Il est interdit d'utiliser la terminologie correcte et a lu la règle d'une définition.


@sellibitze, je suis au courant de cette différence.Je demandez pourquoi const peut corriger le problème mentionné par @paxdiablo


@HTTPTPET Constantes en C ++ Ayez une liaison interne I.E, visible à un seul fichier CPP, vous allez donc ajouter une définition de la constante dans le fichier d'en-tête.


Lequel des CPP exactement? Comme il peut y avoir de nombreux CPP qui incluent le fichier d'en-tête.


Généralement, dans le fichier .CPP par rapport au .H (ou .HPP) dans lequel il est déclaré, mais YMMV, comme d'habitude.


@http, où cela va dépend de l'endroit où cela a du sens. Si vous avez un fichier de source de base de données (par exemple) et AAA appartient à cela, vous vous attendez à ce que vous attendez int AAA dans db.cpp et extern int aaa in db.h . C'est parce que chaque unité de compilation utilisant la base de données comprendrait cet en-tête et un lien avec le fichier d'objet db.o fabriqué à partir de DB.CPP.


@httpinterpret: selon lequel comprend le fichier d'en-tête. Chaque unité de traduction qui a donc sa propre constante de liaison interne dans ce cas.


Si vous entourez votre fichier d'en-tête dans #Ifndef ... vous ne devriez pas avoir de problèmes avec les multiples inclusions / déclarations.


@Raffi, ce n'est pas vrai. Inclure les gardes ne fonctionnent que sur la phase de compilation afin de protéger une seule unité de compilation (par exemple, un fichier source) de plusieurs inclusions. Ils seront pas protéger contre des symboles doublement définis, ce qui entraînera des problèmes au stade de la liaison. Mettez int xzezy; Intérieur Inclure des gardes dans un fichier d'en-tête, incluez-le que dans les fichiers deux C, essayez de les lier ensemble - vous verrez ce que je veux dire.



14
votes

extern code> a ses utilisations. Mais cela implique principalement des "variables globales" qui sont fronça les sourcils. L'idée principale derrière externe code> est de déclarer des choses avec un lien externe. En tant que tel, il est un peu le contraire de statique code>. Mais la liaison externe est dans de nombreux cas la liaison par défaut pour que vous n'ayez pas besoin extern code> dans ces cas. Une autre utilisation de externe code> est: il peut transformer les définitions en déclarations. Exemples:

extern int i;  // Declaration of i with external linkage
               // (only tells the compiler about the existence of i)

int i;         // Definition of i with external linkage
               // (actually reserves memory, should not be in a header file)

const int f = 3; // Definition of f with internal linkage (due to const)
                 // (This applies to C++ only, not C. In C f would have
                 // external linkage.) In C++ it's perfectly fine to put
                 // somethibng like this into a header file.

extern const int g; // Declaration of g with external linkage
                    // could be placed into a header file

extern const int g = 3; // Definition of g with external linkage
                        // Not supposed to be in a header file

static int t; // Definition of t with internal linkage.
              // may appear anywhere. Every translation unit that
              // has a line like this has its very own t object.


2 commentaires

Il y a donc une raison d'utiliser extern const int g; , plutôt que juste const ?


@Castbash: Si vous souhaitez déclarer une constante dans un en-tête, mais définissez sa valeur dans certains fichiers CPP uniquement, vous utiliseriez EXTER Const.