如何防止C中的多个定义?

Jor*_*rdi 39 c multiple-definition-error

我是C新手,我只是想用Code :: Blocks编写一个控制台应用程序.这是(简化)代码:main.c:

#include <stdio.h>
#include <stdlib.h>
#include "test.c" // include not necessary for error in Code::Blocks

int main()
{
    //t = test(); // calling of method also not necessary
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

test.c的:

void test() {}
Run Code Online (Sandbox Code Playgroud)

当我尝试构建此程序时,它会出现以下错误:

*path*\test.c|1|multiple definition of `_ test'|
obj\Debug\main.o:*path*\test.c|1|first defined here|

我没有办法多次定义测试(尽管我不知道下划线的来源)并且似乎不太可能将定义以某种方式包含两次.这是所有代码.

我已经排除了这个错误是由于某些命名冲突与其他函数或文件被称为test或test.c. 请注意,多个和第一个定义位于同一文件的同一行.

有谁知道造成这种情况的原因以及我能做些什么呢?谢谢!

mou*_*iel 85

你实际上编译了test.c两次源代码:

  • 第一次编译时test.c,
  • 第二次编译时main.c包含所有test.c源代码.

main.c为了使用该test()函数,您需要的是一个简单的声明,而不是它的定义.这是通过包含一个test.h包含以下内容的头文件来实现的:

void test(void);
Run Code Online (Sandbox Code Playgroud)

这通知编译器存在具有输入参数和返回类型的这种函数.这个函数的功能(内部{和所有内容})都保留在您的test.c文件中.

在main.c中,替换#include "test.c"#include "test.h".

最后一点:如果您的程序更复杂,您将面临多次包含头文件的情况.为了防止这种情况,标头源有时会被特定的宏定义所包围,例如:

#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED

void test(void);

#endif
Run Code Online (Sandbox Code Playgroud)

  • @LeonixSolutions:我的答案比你引用的更精细.看起来它解决了OP的问题. (2认同)

pax*_*blo 26

下划线由编译器放在那里并由链接器使用.基本路径是:

main.c
test.h ---> [compiler] ---> main.o --+
                                     |
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
Run Code Online (Sandbox Code Playgroud)

因此,您的主程序应包含测试模块的头文件,该头文件应仅包含声明,例如函数原型:

void test(void);
Run Code Online (Sandbox Code Playgroud)

这使得编译器知道它在编译main.c时存在,但实际代码在test.c中,然后是test.o.

这是将两个模块连接在一起的链接阶段.

通过将test.c包含到main.c中,您将在main.o中定义test()函数.据推测,您将链接main.o和test.o,两者都包含函数test().


小智 10

您不应在.c文件中包含其他源文件(*.c).我想你想要一个带有DECLARATION测试函数的头文件( .h),并在单独的.c文件中使用它的DEFINITION.

该错误是由测试函数的多个定义引起的(一个在test.c中,另一个在main.c中)


小智 6

我有类似的问题,我按照方式解决了它.

解决如下:

函数原型声明和全局变量应该在test.h文件中,并且不能在头文件中初始化全局变量.

函数定义和test.c文件中全局变量的使用

如果在头文件中初始化全局变量,则会出现以下错误

`_ test'的多重定义 obj\Debug\main.o:path\test.c | 1 |首先在这里定义|

只是在Header文件中声明全局变量没有初始化应该有效.

希望能帮助到你

干杯


小智 5

如果您已将 test.c 添加到 Code::Blocks 项目中,则该定义将被看到两次 - 一次通过 #include,一次通过链接器。你需要:

  • 删除#include“test.c”
  • 创建一个文件 test.h,其中包含声明: void test();
  • 在 main.c 中包含文件 test.h