我似乎无法摆脱这些看似随机的编译错误。 我得到了大约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,但它似乎没有影响任何东西。
答案 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;
列出项目
while keeping the Actual code in the
cpp :
int Var_Global;
并确保1.包含标题,然后2.链接代码。
将代码链接一次,仅链接一次,并且只有一个数据副本, 如果你整天都可以包含标题,这会告诉其他代码 链接时会有一份数据副本。
我看到很多人将代码放在头文件中,而这可能会起作用 在某些情况下,这是一个坏习惯进入,并会很快或导致问题 后面。
此致
Prashanta