2016-09-10 5 views
0

as400にILE Cプロジェットがあり、グローバル変数externを置くと、グローバル変数または未定義参照の複数の再定義のエラーが発生します。as400 ILE Cグローバル変数複数の再定義

主:ここ

は、その最も単純な形態でコードである

#include "Header1" 

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

ヘッダ1

#ifndef HEADER1 
#define HEADER1 

struct MyStruct{ 
    int x; 
}; 

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

int Foo(void); 

#endif 

ヘッダ1の実装

#include "Header1" 
#include "Header2" 

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

ヘッダ2

#ifndef HEADER2 
#define HEADER2 

int Bar(void); 

#endif 

ヘッダ2の実装

#include "Header2" 
#include "Header1" 

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

各ファイルは罰金コンパイルします。私は次のエラーを取得、それらをリンクしようとする場合にのみ:私のグローバル構造体宣言の前にはexternキーワードで

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

を、私はこのエラーを取得する:

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

ヘッダーが '.h 'で終わらないのはなぜですか? –

+0

ヘッダー1の実装ではセミコロンも忘れています: 'g_myStruct.x = 432'ですが、これを修正してコンパイルする必要があります。エラーを表示できますか? –

+0

@AlterMann as400 QSYSファイルシステムに.hはありません。 –

答えて

1

あなたは、ファイルを含めているheader1.hいくつかの異なるソースファイルで。

これは、g_myStructのいくつかの異なるインスタンスにつながります。したがって、複数の再定義が行われます。

header1.hのこの変数をexternと宣言し、ソースファイルのの1つをにインスタンス化します。

ファイルheader1.h:

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

ファイルheader1.c:

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

は、グローバル変数はグローバル関数のように、かなり多くの仕事たとえば



ヘッダーファイルには、宣言があります。関数については、これは次のようになります。

変数の場合
int Foo(void); // or 'extern int Foo(void);' 

、あなたは(これは機能のためのオプションです)externが必要になります。

extern struct MyStruct g_myStruct; 

次に、実装ファイルで、あなたは定義を置きます:

#include "Header1" 

struct MyStruct g_myStruct; 

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

@ melpomene @barakマノス同時に2つの正解。ありがとうございました。なぜ私はこれをしなければならないのか知っていますか?これは古いCの働きですか?私の例のコードはGCCと完全に動作しますが、ILEではあなたが言ったことをしなければなりません。 –

+0

@BobMarl:コンパイラに関する限り、各ソースファイルは独立したコンパイル単位です。言い換えれば、コンパイラは、現在のソースファイルを処理している間に、以前のソースファイルの「想起がない」ことを意味します。ただし、リンカは同じシンボルの複数の定義を検出します。ボトムラインの 'extern'は、変数が存在し、どこかで宣言されていることをコンパイラが知るためのものです。もちろん、それはまだどこかで宣言(インスタンス化)する必要があります** **ただ一度** - それ以外の場合、リンカはエラーを発行します。 –

+0

@BobMarlこれはCの動作方法です。正直言って、なぜgccで動作するのか分かりません。 – melpomene

関連する問題