2011-07-04 97 views
2

文件a.cc全局變量使用extern的正確方法是什麼?

文件b.cc

#include "a.cc" 

文件main.cc

#include "b.cc" 
extern int a; 

int main() { 


} 

g++ -c a.cc 
g++ -c b.cc 
g++ main.cc a.o b.o 
error: multiple definitions of a 

我在做什麼錯在這裏?

+0

一般而言,您不應該''包含''.cc'文件,只包含'.h'文件。 –

回答

5

您包含一個.cc(或.cpp)文件,這是錯誤的。不要那樣做。你需要一個頭,並且在把extern int a;

// a.h 
// include guards omitted 
extern int a; 

// a.cc 
#include "a.h" 

int a; 

// b.cc 
#include "a.h" 

// main.cc 
#include "a.h" 

int main(){ 
    // use a 
} 
+0

Achh。打敗我吧。 –

+0

我仍然得到相同的錯誤 – Mark

+0

@Mark:這不應該發生,你有所有像這樣的文件?你可能正在編譯'.h'文件嗎?如果是的話,不要那樣做,只編譯'.cc'文件。 – Xeo

1

你是做什麼的鏈接說:你所提供的「A」的多個定義。 a.cc和b.cc都將變量'a'定義爲具有外部鏈接的東西。

不要那樣做!

請勿#include源文件。有些時候你確實想要這樣做,但是再次,有些時候你想使用goto

+0

所有三個文件需要操縱變量。什麼是最好的方式去做這件事? – Mark

+0

_Declare_變量,無論你需要它,最好通過#including一個聲明它的文件。 _只定義一次變量,並且只定義一次。不這樣做是違反標準。 –

0

準確地說是編譯器告訴你 - 你最終在所有三個翻譯單元中定義了定義了a!你想反其道而行之:反覆包含的聲明應該是extern,並且必須只有一個的定義。例如:

// header: stuff.h 
extern int a; 
void foo(); 


// first TU: a.cpp 
#include "stuff.h" 

void foo() { a += 1; } 


// second TU: main.cpp 
#include "stuff.h" 

int a; // `a` is stored in this TU 

int main() { 
    a = 6; 
    foo(); 
    // now a == 7 
} 
0

當使用包括,想象把所有的文件到一個文件中。這基本上是編譯器所看到的,因爲在編譯器階段之前,預處理器都包含了所有內容。

所以你的main.cc開始看起來像這樣。

int a; 
extern int a; 

編譯器認爲這沒關係,因爲沒有初始化的extern只是一個聲明,使內存沒有分配給它。然而,「int a」是一個定義,因此main.o包含爲a分配內存的指令。

鏈接器鏈接後,鏈接器注意到a.o和b.o已經定義了「a」。 「a」,因爲這是它最初定義的地方,「b」是因爲b包含了「a」,它有定義。

要解決這個問題,只需在main.cc中取出#include「b.cc」即可。事實上,完全取出b.cc是因爲它沒有任何意義。

如果你確實想這樣做,就用extern int a爲「a」創建一個名爲a.h的單獨頭文件。然後main.cc和b.cc可以自由包含a.h而不用重新定義a。

相關問題