循环包含导致链接错误的语句

时间:2013-12-08 22:26:44

标签: c++ linker g++ linker-errors

我有一个大型项目(20多个文件),但我设法设置了这个小例子,它重现了我的问题。基本上我有一个文件(A.cpp)包括第二个文件(B.cpp),但第二个文件需要第一个文件中的几个变量和函数。观察:

A.H:

#ifndef _A_H_
#define  _A_H_
static void foo(int _something);
#endif // #ifndef _A_H_

A.cpp:

#include <iostream>
#include "A.h"
#include "B.h"

using namespace std;

static void foo(int _something)
{
   cout << _something << "\n";
}

int main(int argc, char *argv[])
{
   B *b;

   foo ( 123 ); // So we don't get that pesky defined-not-used warning
   b = new B ();
   b->display ( 123 );
}

B.h:

#ifndef _B_H_
#define  _B_H_
#include "A.h"

class B
{
   public:
      B();
      ~B();
      void display ( int x );
};
#endif // #ifndef _B_H_

B.cpp:

#include "B.h"

void B::display ( int x )
{
   foo ( x );
}

我正在编译它,g++ -Wall A.cpp B.cpp -o main但是我得到了这个错误:

A.h:3:13: warning: ‘void foo(int)’ used but never defined [enabled by default]
/tmp/ccFwfZa6.o: In function `main':
A.cpp:(.text+0x54): undefined reference to `B::B()'
/tmp/ccM8SNBK.o: In function `B::display(int)':
B.cpp:(.text+0xd): undefined reference to `foo(int)'
collect2: ld returned 1 exit status

我可以说这是一个链接错误,但我不知道为什么我会收到这个错误。

修改

在我的原始代码中,我仍然收到错误,这次是关于整数的多重定义,这是我得到的错误:

B.o:(.bss+0x4): multiple definition of `some_var'
A.o:(.bss+0x4034): first defined here
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

我正在创建变量some_var,如此

A.H:

#ifndef _A_H_
#define  _A_H_
static void foo(int _something);
int some_var;
#endif // #ifndef _A_H_

当我有那些有条件的警卫时,some_var怎么可能被多次定义?

3 个答案:

答案 0 :(得分:3)

你根本没有B :: B()身体。添加一个,不要忘记析构函数。

另外,从foo()中删除静态。

答案 1 :(得分:1)

问题现在#include s a.h得到int some_var;定义的每个源文件。通常,变量应在标题中声明,在一个源文件中定义。所以在你的标题中你需要

extern int some_var;

并在一个源文件中(大概是a.cpp)

int some_var;

答案 2 :(得分:0)

感谢Pete Becker我找出了问题,主要是因为缺乏对C / C ++所有事物的理解。

  1. extern语句不仅仅用于引用其他头文件的头文件中(即“Bh”编写extern int a,其中a在“Ac”中定义但是也在原始头文件中(在本例中为“啊”)
  2. 我错误地认为定义需要等号(即int a = 1),而int a也是定义。因此,我在“A.h”中定义我的变量时,我应该在“A.h”中声明它extern int a
  3. 在修复上面的2之后,我不断得到undefined reference to a(我确实认为编译器和链接器正在进行小便)。我正在“A.cpp”中搜索int a=...,并且正在定义它的日期。事实证明这个定义是里面一个函数,因此永远不会被定义。
  4. 如果所有其他方法都失败了,请以简单的方式编辑源文件(即删除一个单词并再次输入)以强制进行编译),因为我发现更改头文件并不总是导致完全编译。