2011-07-04 101 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。

相关问题