C语言 “多重定义”、“首先在此处定义”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30821356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:59:06  来源:igfitidea点击:

"Multiple definition", "first defined here" errors

ceclipseincludedefinitionmultiple-definition-error

提问by matt-pielat

I have 3 projects: Server, Clientand Commons. Making header & source pairs in Commonsdoesn't cause any problems and I can access the functions freely from both Serverand Client.

我有 3 个项目:ServerClientCommons。在Commons中制作标头和源代码对不会导致任何问题,我可以从ServerClient自由访问这些功能。

However, for some reason making additional source/header files within Serveror Clientproject always causes multiple definition of (...)and first defined hereerrors.

但是,出于某种原因,在服务器客户端项目中制作额外的源/头文件总是会导致multiple definition of (...)first defined here错误。

Example:

例子:

commands.h(in root dir of the Clientproject)

commands.h(在客户端项目的根目录中)

#ifndef COMMANDS_H_
#define COMMANDS_H_

#include "commands.c"

void f123();

#endif /* COMMANDS_H_ */

commands.c(in root dir of the Clientproject)

commands.c(在客户端项目的根目录中)

void f123(){

}

main.c(in root dir of the Clientproject)

main.c(在客户端项目的根目录中)

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

}

Errors:

错误:

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

Cleaning, rebuilding index, rebuilding projects doesn't help. Neither does restarting the computer.

清理、重建索引、重建项目都无济于事。重启电脑也不行。

回答by Giuseppe Pes

The problem here is that you are including commands.cin commands.hbefore the function prototype. Therefore, the C pre-processor inserts the content of commands.cinto commands.hbefore the function prototype. commands.ccontains the function definition. As a result, the function definition ends up before than the function declaration causing the error.

这里的问题是您包含commands.ccommands.h函数原型之前。因此,C 预处理器会在函数原型之前插入commands.cinto的内容commands.hcommands.c包含函数定义。结果,函数定义在导致错误的函数声明之前结束。

The content of commands.hafter the pre-processor phase looks like this:

commands.h预处理器阶段之后的内容如下所示:

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */

This is an error because you can't declare a function after its definition in C. If you swapped #include "commands.c"and the function declaration the error shouldn't happen because, now, the function prototype comes before the function declaration.

这是一个错误,因为你不能在 C 中定义之后声明一个函数。如果你交换#include "commands.c"了函数声明,那么错误就不应该发生,因为现在函数原型出现在函数声明之前。

However, including a .cfile is a bad practiceand should be avoided. A better solution for this problem would be to include commands.hin commands.cand link the compiled version of command to the main file. For example:

但是,包含.c文件是一种不好的做法,应该避免。对于这个问题更好的解决方案将包括commands.hcommands.c和命令的编译版本链接到主文件。例如:

commands.h

命令.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

commands.c

命令.c

#include "commands.h"

void f123(){} // function definition

回答by andrewrmack

You should not include commands.c in your header file. In general, you should not include .c files. Rather, commands.c should include commands.h. As defined here, the C preprocessor is inserting the contents of commands.c into commands.h where the include is. You end up with two definitions of f123 in commands.h.

您不应在头文件中包含 commands.c。通常,您不应包含 .c 文件。相反,commands.c 应该包含commands.h。如此处所定义,C 预处理器将commands.c 的内容插入到commands.h 中,其中include 所在的位置。您最终会在 commands.h 中得到 f123 的两个定义。

commands.h

命令.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123();

#endif

commands.c

命令.c

#include "commands.h"

void f123()
{
    /* code */
}

回答by Chuanhang.gu

Maybe you included the .cfile in makefile multiple times.

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

回答by TerryE

I am adding this A because I got caught with a bizarre version of this which really had me scratching my head for about a hour until I spotted the root cause. My load was failing because of multiple repeats of this format

我添加这个 A 是因为我发现了一个奇怪的版本,这真的让我摸不着头脑大约一个小时,直到我发现了根本原因。由于多次重复此格式,我的加载失败

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

I turned out to be a bug in my Makefile magic where I had a list of C files and using vpath etc., so the compiles would pick them up from the correct directory in hierarchy. However one C file was repeated in the list, at the end of one line and the start of the next so the gcc load generated by the make had the .ofile twice on the command line. Durrrrh. The multiple definitions were from multiple occurances of the same file. The linker ignored duplicates apart from static initialisers!

我原来是我的 Makefile 魔术中的一个错误,我有一个 C 文件列表并使用 vpath 等,因此编译将从层次结构中的正确目录中选择它们。然而,在列表中重复了一个 C 文件,在一行的末尾和下一行的开头,因此 make 生成的 gcc 负载.o在命令行上有两次该文件。杜尔。多个定义来自同一文件的多次出现。除了静态初始化程序之外,链接器忽略了重复项!