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

gcc/g++ and multiple definitions of global variables

我有几个 .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

因此我没有获得成功的构建。请建议如何摆脱这个错误,并保留这些全局变量。到目前为止,我只使用函数式编程(使用 C++ 库,例如 boost)并且没有自己的 namespaces/objects。

假设您的全局 header 是 (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 将被定义在两个object 文件中。所以链接器会抱怨多个定义。

要克服这个问题,您需要 header 中的 extern 关键字。 extern 关键字告诉编译器该变量在别处定义。因此,不会将新的全局 object 条目写入 object 文件。

更改 global.h 如下:

#ifndef _GLOBAL_H
#define _GLOBAL_H

extern int g_a;

#endif

因此,不会有 int g_a 条目写入 object 文件。但这会导致链接中出现未定义的符号错误。要克服这个问题,请在 a.cppb.cpp 中定义 int g_a,但不要同时在两者中定义。

b.cpp

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

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

你的程序中可以有多个声明,所以通常你设置的东西让你的头文件有ONLY声明, 包含 .cpp 文件中的所有定义。