eclipse “多个定义”、“先在此处定义”错误

xxslljrj  于 2022-11-29  发布在  Eclipse
关注(0)|答案(6)|浏览(275)

我有3个项目:ServerClientCommons。在 Commons 中制作头和源代码对不会引起任何问题,我可以从 ServerClient 自由访问这些功能。
但是,由于某种原因,在 ServerClient 项目中创建附加源/头文件总是会导致multiple definition of (...)first defined here错误。
示例:

commands.h(位于 Client 项目的根目录中)

#ifndef COMMANDS_H_
#define COMMANDS_H_

#include "commands.c"

void f123();

#endif /* COMMANDS_H_ */

commands.c(位于 Client 项目的根目录中)

void f123(){

}

main.c(位于 Client 项目的根目录中)

#include "commands.h"
int main(int argc, char** argv){

}

错误数:

make: *** [Client] Error 1      Client
first defined here              Client
multiple definition of `f123'   commands.c

清理、重建索引、重建项目都没有帮助,重新启动计算机也没有帮助。

mbyulnm0

mbyulnm01#

我有一个类似的问题时,不使用inline为我的全局函数,这是包括在两个地方。

axkjgtzd

axkjgtzd2#

您不应该在头文件中包含commands.c。通常,您不应该包含.c文件。相反,commands.c应该包含commands.h。正如这里所定义的,C预处理器将commands.c的内容插入到commands.h中,其中include为。最后,在commands.h中有两个f123的定义。

命令.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123();

#endif

命令.c

#include "commands.h"

void f123()
{
    /* code */
}
kmb7vmvb

kmb7vmvb3#

也许您在makefile中多次包含了.c文件。

hrysbysz

hrysbysz4#

我添加这个A是因为我遇到了一个奇怪的版本,这个版本让我挠头了大约一个小时,直到我找到了根本原因。

<path>/linit.o:(.rodata1.libs+0x50): multiple definition of `lua_lib_BASE'
<path>/linit.o:(.rodata1.libs+0x50): first defined here

我发现我的Makefile魔法中有一个bug,我有一个C文件列表,并使用vpath等,所以编译器会从层次结构中的正确目录中选择它们。在一行的末尾和下一行的开头,所以make生成的gcc加载在命令行上有两次.o文件。多个定义来自同一文件的多次出现。链接器忽略了除静态初始化程序之外的重复项!

7vhp5slm

7vhp5slm5#

如果定义为“仅头文件”,也会发生此错误。例如:

foo.h :
#ifndef FOO
#define FOO
int myFunc(int a) {
 return a+2;
}

#endif

// There is no foo.c

// Main source files
file1.c :
#include "Foo.h"
<some code>

file2.c :
#include "Foo.h"
<some code>

现在file1.c和file2.c都包含了myFunc()的定义。当它们链接到同一个库时,这将导致链接器错误。

5lhxktic

5lhxktic6#

这里的问题是,您将commands.c包含在函数原型之前的commands.h中。因此,C预处理器将commands.c的内容插入到函数原型之前的commands.h中。commands.c包含函数定义。因此,函数定义在导致错误的函数声明之前结束。
预处理器阶段之后commands.h的内容如下所示:

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */

这是一个错误,因为在C语言中,不能在函数定义之后声明函数。如果交换了#include "commands.c"和函数声明,则不会发生错误,因为现在函数原型在函数声明之前。
但是,包含.c文件是一个不好的做法,应该避免。解决此问题的更好方法是将commands.h包含在commands.c中,并将命令的编译版本链接到主文件。例如:

命令.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

命令.c

#include "commands.h"

void f123(){} // function definition

相关问题