gcc / g ++和全局变量的多个定义

时间:2015-09-27 19:13:54

标签: c++ gcc g++

我有几个.h / .cpp文件,每个文件应该有一个名为“common.h / common.cpp”的文件,因为我在其余的文件中重复使用它的定义。 common.h文件定义了一些有意的全局变量。

我在Linux和gcc 4.4.7下工作。

Compuler可以正常工作,但g ++链接器会抱怨许多情况,例如:

build/Debug/GNU-Linux-x86/StoreData2/spacewx.o:(.data+0x200): multiple definition of `nmdata::names`
build/Debug/GNU-Linux-x86/StoreData2/StoreData2.o:(.data+0x200): first defined here

因此我没有成功构建。请建议如何摆脱这个错误,并保留这些全局变量。我只使用函数式编程(使用诸如boost之类的C ++库),到目前为止还没有自己的命名空间/对象。

2 个答案:

答案 0 :(得分:4)

假设你的全局标题是(global.h):

#ifndef _GLOBAL_H
#define _GLOBAL_H

int g_a;

#endif

如果您有两个源文件,包括global.ha.cppb.cpp,请执行以下操作:

a.cpp

#include "global.h"
/* some source */

b.cpp

#include "global.h"
/* some source */

预处理后,它们看起来像这样(包含的文件被扩展):

a.cpp

int g_a;
/* some source */

b.cpp

int g_a;
/* some source */

因此,如果您编译这些源文件,则将在两个目标文件中定义全局变量int g_a。所以链接器会抱怨多个定义。

要解决此问题,标题中需要extern个关键字。 extern关键字告诉编译器该变量是在其他地方定义的。因此,不会将新的全局对象条目写入目标文件。

更改global.h,如下所示:

#ifndef _GLOBAL_H
#define _GLOBAL_H

extern int g_a;

#endif

因此,将不会将int g_a条目写入目标文件。但这会导致链接中出现未定义的符号错误。要克服这个问题,请在int g_aa.cpp中定义b.cpp,但不能同时定义b.cpp

#include "global.h" int g_a; /* some source */

For each row in table1,
  Find a corresponding row in table2 (with same year and region).
  Multiply the percentage in table1 with value in table2

答案 1 :(得分:1)

程序中的每个变量或函数只能在一个编译单元中定义一次。如果你在多个编译单元中定义任何东西,你通常会得到一个链接错误,就像你看到的那样,虽然正式,它是未定义的行为,所以编译器可能没有给出诊断和你的程序只会行为不端。

您的程序中可以包含多个声明,因此通常需要进行设置,以便您的头文件具有 ONLY 声明,其中包含所有定义。 cpp文件。