"多重定义","此处首先定义"错误

mat*_*lat 15 c eclipse definition include multiple-definition-error

我有3个项目:服务器,客户端共享.在Commons中创建头和源对不会导致任何问题,我可以从服务器客户端自由访问这些功能.

然而,由于某些原因使中附加源/头文件服务器客户端的项目总是会引起multiple definition of (...)first defined here错误.

例:

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

#ifndef COMMANDS_H_
#define COMMANDS_H_

#include "commands.c"

void f123();

#endif /* COMMANDS_H_ */
Run Code Online (Sandbox Code Playgroud)

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

void f123(){

}
Run Code Online (Sandbox Code Playgroud)

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

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

}
Run Code Online (Sandbox Code Playgroud)

错误:

make: *** [Client] Error 1      Client
first defined here              Client
multiple definition of `f123'   commands.c
Run Code Online (Sandbox Code Playgroud)

清洁,重建索引,重建项目没有帮助.也没有重新启动计算机.

Ian*_*nny 30

inline当我不使用包含在两个地方的全局函数时,我遇到了类似的问题。

  • @亚历克斯K。据我了解...在这种情况下将内联视为静态。当文件包含在多个源中时,它仅编译一次,并在后续使用时引用回原始对象。 (2认同)

Giu*_*Pes 23

这里的问题是要包括commands.ccommands.h函数原型之前.因此,C预处理器插入的含量commands.ccommands.h函数原型之前.commands.c包含函数定义.因此,函数定义在导致错误的函数声明之前结束.

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

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */
Run Code Online (Sandbox Code Playgroud)

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

但是,包含.c文件是一种不好的做法,应该避免使用.针对此问题的更好解决方案是将编译版本的命令包含commands.hcommands.c主文件中并将其链接到主文件.例如:

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif
Run Code Online (Sandbox Code Playgroud)

commands.c

#include "commands.h"

void f123(){} // function definition
Run Code Online (Sandbox Code Playgroud)

  • @delive关键是要了解您永远不会包含.c文件。尝试包括相应的.h文件 (3认同)
  • 即使不包含 `.c` 文件,如果您在头文件中 _define_ 一个函数,这个错误仍然会发生。所以除非你有一个令人信服的理由让你的代码 [header-only](https://en.wikipedia.org/wiki/Header-only),你应该总是在 `.h` 文件中_declare_你的函数,_define_它在相应的“.c”中,并且只包含“.h”文件。 (3认同)

小智 7

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

命令.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123();

#endif
Run Code Online (Sandbox Code Playgroud)

命令.c

#include "commands.h"

void f123()
{
    /* code */
}
Run Code Online (Sandbox Code Playgroud)