2016-09-10 1 views
0

J'ai un projet ILE C sur l'as400 qui, en étant lié, me donne soit une erreur de redéfinition multiple des variables globales ou des références indéfinies si je mets la variable globale extern.as400 ILE C variable multiple redefition

Voici le code dans sa forme la plus simple:

principale:

#include "Header1" 

int main(int argc, char** argv){ 
    int x = Foo(); 
    return 0; 
} 

Header1

#ifndef HEADER1 
#define HEADER1 

struct MyStruct{ 
    int x; 
}; 

struct MyStruct g_myStruct; /* My global struct variable. */ 

int Foo(void); 

#endif 

Header1 mise en œuvre

#include "Header1" 
#include "Header2" 

int Foo(void){ 
    g_myStruct.x = 432; 
    return Bar(); 
} 

Header2

#ifndef HEADER2 
#define HEADER2 

int Bar(void); 

#endif 

Header2 mise en œuvre

#include "Header2" 
#include "Header1" 

int Bar(void){ 
    return g_myStruct.x; 
} 

Chaque fichier compile bien. Seulement lorsque je tente de les relier je reçois l'erreur suivante:

Multiple strong definitions . . . . . . . . . : 2 
    Symbol Type  Library  Object  Bound  Identifier 
       *MODULE MYLIB  1   *YES  g_myStruct 
       *MODULE MYLIB  I2   *YES  g_myStruct 

Avec le mot-clé extern devant ma déclaration globale struct, je reçois cette erreur:

Unresolved references . . . . . . . . . . . . : 2 
    Symbol Type  Library  Object  Bound  Identifier 
       *MODULE MYLIB  I1   *YES  g_myStruct 
       *MODULE MYLIB  I2   *YES  g_myStruct 
+0

Pourquoi vos en-têtes ne se terminent pas par '.h'? –

+0

Vous oubliez également le point-virgule dans l'implémentation de Header1: 'g_myStruct.x = 432' mais en corrigeant cela, vous devez compiler, pouvez-vous afficher l'erreur? –

+0

@AlterMann Il n'y a pas de .h sur le système de fichiers as400 QSYS. –

Répondre

1

Vous incluez fichier header1.h dans plusieurs fichiers source différents.

Cela conduit à plusieurs instances différentes de g_myStruct, donc redéfinition multiple.

cette Declare extern variables dans un fichier header1.h et instancier dans un des fichiers source.


Par exemple:

fichier header1.h:

extern struct MyStruct g_myStruct; /* My global struct variable. */ 

fichier header1.c:

struct MyStruct g_myStruct; /* My global struct variable. */ 
1

Les variables globales fonctionnent à peu près comme des fonctions globales .


Dans le fichier d'en-tête, vous devez mettre une déclaration.Pour les fonctions, cela ressemble à:

int Foo(void); // or 'extern int Foo(void);' 

Pour les variables, vous avez besoin extern (facultatif pour les fonctions):

extern struct MyStruct g_myStruct; 

Ensuite, dans le fichier de mise en œuvre, vous mettez les définitions:

#include "Header1" 

struct MyStruct g_myStruct; 

int Foo(void){ 
    ... 
} 
+0

@ melpomene @barak manos Deux bonnes réponses à la fois. Je vous remercie. Sais-tu pourquoi je dois faire ça? Est-ce à quel point C travaillait-il? Le code dans mon exemple fonctionne parfaitement avec GCC, mais dans ILE, je dois faire ce que vous avez dit. –

+0

@BobMarl: En ce qui concerne le compilateur, chaque fichier source est une unité de compilation indépendante. En d'autres termes, le compilateur "n'a aucun souvenir" d'un fichier source précédent, alors qu'il travaille sur le fichier source en cours. Le lieur, cependant, détecte plusieurs définitions du même symbole. La ligne du bas, 'extern' est juste pour le compilateur de savoir que la variable existe et est déclarée quelque part. Bien sûr, il doit toujours être déclaré (instancié) quelque part, et ** seulement une fois ** - sinon l'éditeur de liens émettra une erreur. –

+0

@BobMarl C'est toujours comme cela que fonctionne C. Pour être honnête, je ne sais pas pourquoi cela fonctionne dans gcc. – melpomene