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

gcc/g++ and multiple definitions of global variables

本文关键字:定义 全局变量 g++ Gcc      更新时间:2023-10-16

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

我在Linux和gcc 4.4.7下工作。

强迫症做得很好,但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),到目前为止没有自己的名称空间/对象。

假设您的全局标头为(global.h):

#ifndef _GLOBAL_H
#define _GLOBAL_H
int g_a;
#endif

如果您有两个源文件,包括global.h: a.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条目被写入目标文件。但这将导致链接中的未定义符号错误。为了克服这个问题,在a.cppb.cpp中定义int g_a,但不能在两者中都定义。

b.cpp

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

程序中的每个变量或函数只能在一个编译单元中定义一次。如果您在多个编译单元中定义任何内容,您通常会得到一个链接错误,如您所见,尽管官方称其为未定义行为,因此编译器可能不会给出诊断,您的程序将只是错误行为。

你可以有多个声明的东西在你的程序中,所以通常你设置的东西,使你的头文件有只有声明,所有的定义在。cpp文件。