2016-05-02 8 views
4

私はGCCに問題があります。私のグローバル変数を見つけることができません。GCCリンカーは、既存のグローバル変数への未定義参照について文句を言います

a.cpp:

#include "b.h" 

const char * const g_test = "blah blah"; 

int main(){ 
    test(); 
    return 0; 
} 

b.cpp:

#include <iostream> 
#include "a.h" 

using namespace std; 

void test(){ 
    cout << g_test; 
} 

ああ:

extern const char * const g_test; 

BH:

私は、問題を特定するために、サンプルC++プロジェクトを作成しました
void test(); 

は、私はこのようにそれをコンパイルします。

$ g++ -o a.o -c a.cpp 
$ g++ -o b.o -c b.cpp 
$ g++ -o test a.o b.o 
b.o: In function `test()': 
b.cpp:(.text+0x7): undefined reference to `g_test' 
collect2: error: ld returned 1 exit status 

何も変更しない最後のコマンドでオブジェクトファイルの順序を変更します。

なぜリンカはエラーをスローしますか?私は単に実行可能な印刷 "愚かな言葉"を作成することを期待していたが、何とかエラーが表示されます。私はそれが失敗する理由を見ません。

+0

'a.cpp'は' a.h'をインクルードする必要はありませんか? – NathanOliver

+1

私は、constにはC++の内部リンケージがあるという事実と関係があると思います。 –

+0

@Haatschii私の文字列は最後のバイナリに2回含まれませんか? – NieDzejkob

答えて

6

const変数g_testは、内部リンケージのみを持ちます。つまり、.cppファイルでのみ使用できます。定義されています。 const変数グローバルリンケージ(すなわち、他のソースファイルから、それを使用可能に)あなたがexternキーワードを追加する必要があり、すなわち:

#include "b.h" 

extern const char * const g_test = "blah blah"; 

int main(){ 
    test(); 
    return 0; 
} 

を与えるために別の方法として、あなたが最初にa.hを含めることができます。その場合、a.cppを翻訳するときにextern前方宣言がコンパイラに認識されます。

ただし、g_testexternキーワードなし)の定義をヘッダーファイルに移動することをお勧めします。このように、コンパイラはすべてのコンパイル単位でg_testの定義を認識しており、コンパイル時にそれを使用してconst式を評価することができます。

0

最も簡単な解決策は、キーワードexternを定義に追加することです。私は奇妙に見えますが、externは通常、宣言ではなく、宣言になりますが、コンパイラはそれを値として与えるため、定義(インスタンス化)として扱います。

クエンティンのコメント(stolen from Quentin)のリンクは、その理由の素晴らしい説明です。

関連する問題