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

Ask*_*mov -2 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
Run Code Online (Sandbox Code Playgroud)

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

jnb*_*mez 5

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

#ifndef _GLOBAL_H
#define _GLOBAL_H

int g_a;

#endif
Run Code Online (Sandbox Code Playgroud)

如果您有两个源文件,包括global.h:a.cppb.cpp这样的:

a.cpp

#include "global.h"
/* some source */
Run Code Online (Sandbox Code Playgroud)

b.cpp

#include "global.h"
/* some source */
Run Code Online (Sandbox Code Playgroud)

预处理后,它们将如下所示(包含的文件已展开):

a.cpp

int g_a;
/* some source */
Run Code Online (Sandbox Code Playgroud)

b.cpp

int g_a;
/* some source */
Run Code Online (Sandbox Code Playgroud)

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

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

更改global.h如下:

#ifndef _GLOBAL_H
#define _GLOBAL_H

extern int g_a;

#endif
Run Code Online (Sandbox Code Playgroud)

因此,不会有任何int g_a条目被写入目标文件。但这会导致链接时出现未定义的符号错误。克服int g_aa.cppb.cpp但不是在两者中的定义。

b.cpp

#include "global.h"
int g_a;
/* some source */
Run Code Online (Sandbox Code Playgroud)