“多重定义”,“此处首先定义”错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“多重定义”,“此处首先定义”错误相关的知识,希望对你有一定的参考价值。
我有3个项目:服务器,客户端和共享。在Commons中创建头和源对不会导致任何问题,我可以从服务器和客户端自由访问这些功能。
但是,由于某些原因,在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
清洁,重建索引,重建项目没有帮助。也没有重新启动计算机。
这里的问题是你在函数原型之前将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
,并将编译后的命令版本链接到主文件。例如:
commands.h
#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123(); // function declaration
#endif
commands.c
#include "commands.h"
void f123(){} // function definition
您不应在头文件中包含commands.c。通常,您不应包含.c文件。而是,commands.c应该包含commands.h。如此处所定义的,C预处理器将commands.c的内容插入到command.h中,其中include是。你最终在commands.h中有两个f123的定义。
commands.h
#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123();
#endif
commands.c
#include "commands.h"
void f123()
{
/* code */
}
也许你多次在makefile中包含.c
文件。
我添加了这个A因为我遇到了一个奇怪的版本,这让我头疼了大约一个小时,直到我发现根本原因。由于此格式的多次重复,我的负载失败了
<path>/linit.o:(.rodata1.libs+0x50): multiple definition of `lua_lib_BASE'
<path>/linit.o:(.rodata1.libs+0x50): first defined here
我原来是我的Makefile魔法中的一个错误,我有一个C文件列表和使用vpath等,所以编译将从层次结构中的正确目录中选择它们。但是在列表中重复了一个C文件,在一行的末尾和下一行的开头,因此make生成的gcc负载在命令行上有两次.o
文件。 Durrrrh。多个定义来自同一文件的多个出现。链接器忽略了静态初始化器之外的重复项!
以上是关于“多重定义”,“此处首先定义”错误的主要内容,如果未能解决你的问题,请参考以下文章