“C ++编译器错误的多重定义

时间:2009-03-26 11:53:37

标签: c++ linker

我似乎无法摆脱这些看似随机的编译错误。 我得到了大约4个错误,例如:

multiple definition of `draw_line(float, float, float, float)'

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

在方法中间标记。

我也一直在multiple definition of `stack'处于另一种方法的中间。 stack是完全不同文件中的全局变量。它甚至没有在我收到错误的文件中提到。

我尝试将容易出错的文件分成.h和.cpp文件(最初只是一个.cpp),并且没有改变错误...

我没有重复的方法。我只有一个#include的lines.h,并且在开头有一个#ifndef子句。所有这些错误都出现在.cpp文件中。

任何想法可能是什么?

好吧,我收到了代码:

lines.cpp是我从教师那里收到的转换后的.c文件。为了以防万一,我包含了makefile,因为我总是遇到问题。我还注释了错误在文件中标记的确切位置,但它们看起来很随意,所以我不知道它是否特别重要。我放弃了.h文件,因为它没有解决任何问题或帮助。我相信没有它就会更容易找到错误。

这是请求的main.cpp file(没有.h)。


我重新制作了lines.h文件,因为我仍然收到:

multiple definition of `draw_line(float, float, float, float)'

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'
line.cpp文件中的

错误,但multiple definition of `stack'错误现在位于ThreeD.cpp文件中的随机位置(现在由注释标记)。 更新:此错误已修复,文件已修改为显示:

我搞砸了一些全局变量extern,但它似乎没有影响任何东西。

9 个答案:

答案 0 :(得分:34)

您可能在头文件中包含函数定义。包含inline关键字,以便它们不会被每个目标文件导出,也不会将它们放在自己的.cpp文件中。

对于全局变量,您需要在头文件中使用extern关键字。否则,每个目标文件都会导出它们自己的变量,并且链接器会混淆哪个是正确的。

答案 1 :(得分:14)

为什么你在ThreeD.cpp中#include lines.cpp?这很不寻常。

你的makefile需要lines.o,所以你要编译lines.cpp。 lines.cpp中定义的任何内容都将在lines.o中以及ThreeD.o中。

在lines.cpp中有一个有趣的评论:

Don't forget to put declarations in your .h files. 

我认为教师希望你将lines.cpp分解为.h和.cpp。

摘自lines.cpp:

/* These go in your .h file or in lines.h */
/*

Line drawing header.

*/


void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
                  float *, float *);

我怀疑这两个声明是应该在lines.h中唯一的。

答案 2 :(得分:3)

请发布一些代码段。也许你在类声明和外部都定义了你的方法?

class X {
    void foo();    // No definition, just declaration
    void bar() {}  // Declaration + definition
};

void X::foo() {}    // First Definition, OK
void X::bar() {}    // Already defined, ERROR

答案 3 :(得分:3)

检查是否包含拼写错误的警卫 检查您的制作选项,也许有人编译成多个目标文件 尝试排除部分文件和代码,直到找不到错误原因。

<强>编辑:
修复包含* .cpp文件。它们应该联系在一起。

答案 4 :(得分:3)

如前所述 - 这里没有足够的信息来正确诊断。

但是如果在头文件而不是源(cpp)文件中定义了draw_line等,那么您可能会在头文件中声明为内联的方法,这些方法实际上并未正确内联。在这种情况下,包含标头的每个.cpp文件将生成自己的draw_line函数定义,并在链接时生成警告。

如果您使用的#defined INLINE宏来自已被遗忘或删除的系统标头,并且由于某种原因INLINE被预处理为无效,则会发生这种情况。

E.g:

//Lines.h

#define GCCC //Note the typo

#if defined(GCC)
#define INLINE inline
#elif defined (MSVC)
#define INLINE __inline
#else

#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif

INLINE void draw_line(float x1, float y1, float x2, float y2)
{
   //Draw the line
}

//File1.cpp
#include "lines.h" //will define draw_line

//File2.cpp
#include "lines.h" //will also define draw_line

链接File1.cpp和File2.cpp会产生多个声明错误

答案 5 :(得分:2)

#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */

删除或评论这些行,这对我有用

答案 6 :(得分:1)

多个定义错误是链接器错误,但没有更多信息,很难诊断它们。检查同一文件在链接器命令中没有出现两次,并且头文件只包含声明,没有定义。

答案 7 :(得分:1)

没有看到代码,真的没有帮助你。编译器明确声称与您相反( 至少有一个重复的定义)。

尝试使用最少示例重现错误。您是否尝试在命令行中编译Eclipse之外的代码?结果如何?

答案 8 :(得分:0)

嗨,我在这里看到基本规则适用于ll。我将解释这些错误中的事情是如何工作的,以及那些错误: 我们举一个 “制作全局变量”

的例子

对于cpp文件,请勿混淆头文件。 标题只是允许多个文件项目具有共同点 接口 在链接之前。

1.列表项

您应该在标题中提供有关全局变量的信息:

extern int Var_Global;

  1. 列出项目

    while keeping the Actual code in the
    cpp :
    
    int Var_Global;
    
  2. 并确保1.包含标题,然后2.链接代码。

    将代码链接一次,仅链接一次,并且只有一个数据副本, 如果你整天都可以包含标题,这会告诉其他代码 链接时会有一份数据副本。

    我看到很多人将代码放在头文件中,而这可能会起作用 在某些情况下,这是一个坏习惯进入,并会很快或导致问题 后面。

    此致

    Prashanta