2016-09-10 2 views
0

Ich habe ein ILE C Projekt auf dem as400 welches, wenn es verbunden wird, mir entweder einen Fehler der mehrfachen Neudefinition von globalen Variablen oder undefinierten Verweisen gibt, wenn ich die globale Variable extern setze.as400 ILE C globale Variable mehrfache Neudefinition

Hier ist der Code in seiner einfachsten Form:

Haupt:

#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 Implementierung

#include "Header1" 
#include "Header2" 

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

Header2

#ifndef HEADER2 
#define HEADER2 

int Bar(void); 

#endif 

Header2 Implementierung

#include "Header2" 
#include "Header1" 

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

Jede Datei kompiliert in Ordnung. Nur wenn ich versuche, sie mir folgende Fehlermeldung erhalten zu verknüpfen:

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

Mit dem Schlüsselwort extern vor meiner globalen Strukturdeklaration, bekomme ich diesen Fehler:

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

Warum enden Ihre Header nicht mit '.h'? –

+0

Sie vergessen auch das Semikolon in der Header1-Implementierung: 'g_myStruct.x = 432', aber das reparieren muss es kompilieren, können Sie den Fehler anzeigen? –

+0

@AlterMann Es gibt kein .h im as400 QSYS-Dateisystem. –

Antwort

1

Du einschließlich Datei header1.h in mehreren verschiedenen Quelldateien.

Dies führt zu mehreren unterschiedlichen Instanzen von g_myStruct, also mehrfacher Neudefinition.

Declare diese Variable extern in Datei header1.h und instanziiert es in ein der Quelldateien.


Zum Beispiel:

Datei header1.h:

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

Datei header1.c:

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

Globale Variablen arbeiten ziemlich viel wie globale Funktionen .


In die Header-Datei legen Sie eine Deklaration.Für Funktionen, das sieht aus wie:

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

für Variablen, die Sie benötigen extern (dies ist optional für Funktionen):

extern struct MyStruct g_myStruct; 

Dann in der Implementierungsdatei, setzen Sie die Definitionen:

#include "Header1" 

struct MyStruct g_myStruct; 

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

@ melpomene @barak manos Zwei richtige Antworten zur gleichen Zeit. Vielen Dank. Weißt du, warum ich das tun muss? Funktioniert das alte C? Der Code in meinem Beispiel funktioniert perfekt mit GCC, aber in ILE muss ich tun, was Sie gesagt haben. –

+0

@BobMarl: Soweit der Compiler betroffen ist, ist jede Quelldatei eine unabhängige Kompilierungseinheit. Mit anderen Worten, der Compiler "hat keine Erinnerung" an irgendeine vorherige Quelldatei, während er an der aktuellen Quelldatei arbeitet. Der Linker erkennt jedoch mehrere Definitionen desselben Symbols. Die untere Zeile "extern" dient nur dazu, dass der Compiler weiß, dass die Variable existiert und irgendwo deklariert ist. Natürlich muss es irgendwo (instanziiert) und ** nur einmal ** deklariert werden - andernfalls gibt der Linker einen Fehler aus. –

+0

@BobMarl So funktioniert C noch. Um ehrlich zu sein, ich weiß nicht, warum es in gcc funktioniert. – melpomene