2012-11-27 2 views
0

J'ai une confusion à propos des structures externes. Je dois définir une instance globale de la structure dans un fichier autre que celui dans lequel la structure est définie (comme une variable RAM dont je ne sais pas exactement ce que c'est). Ci-dessous un exemple que GCC peut compiler et il fonctionne correctement tandis que Code Composer Studio donne des erreurs de compilation.Structures externes et en-têtes multiples

Je veux savoir où est le problème, comment compiler GCC et où/comment utiliser la déclaration extern.

Tout commentaire serait apprécié.

Person.h

#ifndef PERSON_H 
#define PERSON_H 
struct person { 
    int age; 
}; 
typedef struct person PERSON; 
void modifyPerson(); 
#endif // PERSON_H 

personRam.h

#ifndef PERSONRAM_H 
#define PERSONRAM_H 
#include "person.h" 
PERSON p1; 
#endif // PERSONRAM_H 

modifyPerson.c

#include "person.h" 
#include "personRam.h" 
void modifyPerson() { 
    p1.age = 10; 
} 

main.c

#include <stdio.h> 
#include "person.h" 
#include "personRam.h" 
int main() { 
    modifyPerson(); 
    printf("%d", p1.age); 
    return 0; 
} 
+1

Pour avoir une structure externe, vous devez utiliser mot-clé 'extern' au moins une fois. Tu ne l'as pas fait. Alors, où est la structure externe? Nulle part. Vous avez des instances en double de cette structure. GCC est en train de trop pardonner pour vos erreurs. –

+1

http://c-faq.com/decl/decldef.html – hmjd

+0

@Vlad Lazarenko Où sont les doublons? Je l'ai déclaré une fois en personneRam.h. Ai-je tort? – groove

Répondre

1

Sur quel système d'exploitation compilez vous, et pour lequel le système cible?

Pour ce que ça vaut, Linux (& Unix-es) et Windows ont des sémantiques de liaison différentes. Lire Levine's "Linkers & Loaders" livre pour plus de détails.

+0

Je suis sur MS Windows ciblant Windows avec GCC et un DSP avec CCS. – groove

3

Vous ne devriez pas obtenir une erreur de compilation, mais une erreur de lien, en disant que p1 est défini plusieurs fois. Au moins c'est ce que je suppose est le problème.

La raison est que définit la variable dans un fichier d'en-tête, que vous incluez ensuite dans plusieurs fichiers source. Cela signifie que la définition se trouve dans les deux fichiers sources (la directive #include du préprocesseur place littéralement le contenu du fichier d'en-tête à la place de l'instruction "include").

Si vous déclariez la variable comme extern dans le fichier d'en-tête et définir dans un fichier source, il devrait fonctionner.

Ainsi, dans personRam.h

extern PERSON p1; 

Et dans l'un des fichiers source:

PERSON p1; 
+0

Ce dont j'ai besoin, c'est de définir 'p1' dans _personRam.h_. Puis-je le faire? Donc au lieu d'inclure _personRam.h_ dans tous les fichiers dont j'ai besoin de 'p1', je devrais' extern PERSO p1' dans ces fichiers. Ai-je tort? À propos, votre correction à propos de l'erreur du compilateur-éditeur de liens est wright. – groove

+1

@groove Oui cela fonctionnerait, mais je préférerais créer un fichier source 'personRam.c' pour la définition et avoir la déclaration' extern' dans le fichier d'en-tête, et inclure le fichier d'en-tête dans tous les fichiers ayant besoin de cette variable. –

+0

Maintenant, mon _main.c_ et _modifyPerson.c_ n'incluent pas _personRam.h_ mais ils incluent _globals.h_ qui a simplement 'extern PERSON p1;'. Si je déclare 'PERSON p1;' dans _personRam.h_, cela donne une erreur; mais à la place j'ai ajouté _RamRam.c_ qui a '#include" personRam.h "' et 'PERSON p1;'. Cela compile, mais je sens toujours que je fais quelque chose de mal (donc j'agis cette bête). – groove