文件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
我在做什麼錯在這裏?
文件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
我在做什麼錯在這裏?
您包含一個.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
}
你是做什麼的鏈接說:你所提供的「A」的多個定義。 a.cc和b.cc都將變量'a'定義爲具有外部鏈接的東西。
不要那樣做!
請勿#include源文件。有些時候你確實想要這樣做,但是再次,有些時候你想使用goto
。
所有三個文件需要操縱變量。什麼是最好的方式去做這件事? – Mark
_Declare_變量,無論你需要它,最好通過#including一個聲明它的文件。 _只定義一次變量,並且只定義一次。不這樣做是違反標準。 –
準確地說是編譯器告訴你 - 你最終在所有三個翻譯單元中定義了定義了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
}
當使用包括,想象把所有的文件到一個文件中。這基本上是編譯器所看到的,因爲在編譯器階段之前,預處理器都包含了所有內容。
所以你的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。
一般而言,您不應該''包含''.cc'文件,只包含'.h'文件。 –