【问题标题】:"multiple definition" linker error [duplicate]“多重定义”链接器错误[重复]
【发布时间】:2018-08-09 22:31:36
【问题描述】:

我有四个要编译的 C++ 文件。两个是.h,两个是.cpp。我创建了一个生成两个对象并使用 g++ 编译它们的生成文件。在链接器坚持定义两次的 .h 文件之一中定义了一个 int 。我究竟做错了什么? 这些是源文件:

“foo.cpp”

#include "foo.h"
#include "bar.h"
int main ()
{
    X();
}

“foo.h”

#ifndef j
#define j
bool a;
#endif

“bar.cpp”

#include "bar.h"
int X()
{
    b = 0;
    return b;
}

"bar.h"

#ifndef k
#define k
int b;
int X();
#endif

“生成文件”

exec: foo.o bar.o
g++ -oexec foo.o bar.o

foo.o: foo.cpp foo.h
bar.o: bar.cpp bar.h

这是我得到的编译错误:

/usr/bin/ld: bar.o:(.bss+0x0): multiple definition of `b'; foo.o:(.bss+0x4): first defined here
collect2: error: ld returned 1 exit status

附:不,这不是任务的一部分。我为这篇文章做了一个简化的例子。

【问题讨论】:

  • 您不应该在标题中定义变量。当您包含标题时,它会导致在多个翻译单元中定义变量。
  • 就像错误所说的那样,您有多个b 的定义,一个在bar.h 中,一个在bar.cpp 中。您应该告诉编译器 bar.h 中提到的 b 在其他地方定义为 extern int b;
  • 补充一下@drescherjm 所说的,如果您需要在头文件中声明一个变量(以便它可以在多个.cpp 文件中使用),请将其设为“extern”。这与将类(非内联)的数据成员设为静态非常相似。
  • 每个包含 bar.h 的翻译单元(可能是 cpp 文件)都有自己的int b;,而糟糕的链接器无法处理。包含保护 #ifndef k 将防止在该翻译单元中包含多个标题,但无法帮助处理多个翻译单元,这就是您在这里遇到的问题。
  • @alterigel 最重要的是,不仅仅是 .h 中有一个,.cpp 中有一个 - 将它放在 .h 中可能会导致这个问题正常的代码库,因为标头可能会包含在多个 .cpp 文件中(即使使用仅保护来自同一编译单元(.cpp 文件)的多个包含的包含保护)

标签: c++ linker multiple-definition-error


【解决方案1】:

你定义了变量

bool a;
int b;

在头文件中,这些文件包含在多个源代码中,每个源代码都在生成的目标文件中创建一个定义。

您应该避免在头文件中声明变量(非静态类成员除外)。如果你真的需要在头文件中传达这样一个变量的存在,请将其声明为extern

// foo.h
extern int b;      // declares the existence of a variable named b

// foo.cpp
#include foo.h
int b;             // keeps the promise made in foo.h

// bar.h
#include foo.h
b = 2;             // modifies the variable b in foo.cpp

【讨论】:

  • 你不认为这可能是一个骗局,应该这样关闭吗?
  • 不是骗子,我真的找不到重复的帖子。
  • @DanielSmith 这应该有很多重复项。这是一个常见的初学者错误。话虽如此,找到确切的搜索词并不总是那么容易..
猜你喜欢
  • 2013-07-19
  • 2018-11-23
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多