我有3个项目:Server,Client 和 Commons。在 Commons 中制作头和源代码对不会引起任何问题,我可以从 Server 和 Client 自由访问这些功能。
但是,由于某种原因,在 Server 或 Client 项目中创建附加源/头文件总是会导致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
清理、重建索引、重建项目都没有帮助,重新启动计算机也没有帮助。
6条答案
按热度按时间mbyulnm01#
我有一个类似的问题时,不使用
inline
为我的全局函数,这是包括在两个地方。axkjgtzd2#
您不应该在头文件中包含commands.c。通常,您不应该包含.c文件。相反,commands.c应该包含commands.h。正如这里所定义的,C预处理器将commands.c的内容插入到commands.h中,其中include为。最后,在commands.h中有两个f123的定义。
命令.h
命令.c
kmb7vmvb3#
也许您在makefile中多次包含了
.c
文件。hrysbysz4#
我添加这个A是因为我遇到了一个奇怪的版本,这个版本让我挠头了大约一个小时,直到我找到了根本原因。
我发现我的Makefile魔法中有一个bug,我有一个C文件列表,并使用vpath等,所以编译器会从层次结构中的正确目录中选择它们。在一行的末尾和下一行的开头,所以make生成的gcc加载在命令行上有两次
.o
文件。多个定义来自同一文件的多次出现。链接器忽略了除静态初始化程序之外的重复项!7vhp5slm5#
如果定义为“仅头文件”,也会发生此错误。例如:
现在file1.c和file2.c都包含了myFunc()的定义。当它们链接到同一个库时,这将导致链接器错误。
5lhxktic6#
这里的问题是,您将
commands.c
包含在函数原型之前的commands.h
中。因此,C预处理器将commands.c
的内容插入到函数原型之前的commands.h
中。commands.c
包含函数定义。因此,函数定义在导致错误的函数声明之前结束。预处理器阶段之后
commands.h
的内容如下所示:这是一个错误,因为在C语言中,不能在函数定义之后声明函数。如果交换了
#include "commands.c"
和函数声明,则不会发生错误,因为现在函数原型在函数声明之前。但是,包含
.c
文件是一个不好的做法,应该避免。解决此问题的更好方法是将commands.h
包含在commands.c
中,并将命令的编译版本链接到主文件。例如:命令.h
命令.c