How to prevent multiple definitions in C?

CMultiple Definition-Error

C Problem Overview


I'm a C newbie and I was just trying to write a console application with Code::Blocks. Here's the (simplified) code: 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;
}

test.c:

void test() {}

When I try to build this program, it gives the following errors:

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

There is no way that I'm multiply defining test (although I don't know where the underscore is coming from) and it seems highly unlikely that the definition is somehow included twice. This is all the code there is.

I've ruled out that this error is due to some naming conflict with other functions or files being called test or test.c. Note that the multiple and the first definition are on the same line in the same file.

Does anyone know what is causing this and what I can do about it? Thanks!

C Solutions


Solution 1 - C

You actually compile the source code of test.c twice:

  • The first time when compiling test.c itself,
  • The second time when compiling main.c which includes all the test.c source.

What you need in your main.c in order to use the test() function is a simple declaration, not its definition. This is achieved by including a test.h header file which contains something like:

void test(void);

This informs the compiler that such a function with input parameters and return type exists. What this function does ( everything inside { and } ) is left in your test.c file.

In main.c, replace #include "test.c" by #include "test.h".

A last point: with your programs being more complex, you will be faced to situations when header files may be included several times. To prevent this, header sources are sometimes enclosed by specific macro definitions, like:

#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED

void test(void);

#endif

Solution 2 - C

The underscore is put there by the compiler and used by the linker. The basic path is:

main.c
test.h ---> [compiler] ---> main.o --+
                                     |
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe

So, your main program should include the header file for the test module which should consist only of declarations, such as the function prototype:

void test(void);

This lets the compiler know that it exists when main.c is being compiled but the actual code is in test.c, then test.o.

It's the linking phase that joins together the two modules.

By including test.c into main.c, you're defining the test() function in main.o. Presumably, you're then linking main.o and test.o, both of which contain the function test().

Solution 3 - C

You shouldn't include other source files (*.c) in .c files. I think you want to have a header (.h) file with the DECLARATION of test function, and have it's DEFINITION in a separate .c file.

The error is caused by multiple definitions of the test function (one in test.c and other in main.c)

Solution 4 - C

I had similar problem and i solved it following way.

Solve as follows:

Function prototype declarations and global variable should be in test.h file and you can not initialize global variable in header file.

Function definition and use of global variable in test.c file

if you initialize global variables in header it will have following error

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

Just declarations of global variables in Header file no initialization should work.

Hope it helps

Cheers

Solution 5 - C

Including the implementation file (test.c) causes it to be prepended to your main.c and complied there and then again separately. So, the function test has two definitions -- one in the object code of main.c and once in that of test.c, which gives you a ODR violation. You need to create a header file containing the declaration of test and include it in main.c:

/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */

Solution 6 - C

If you have added test.c to your Code::Blocks project, the definition will be seen twice - once via the #include and once by the linker. You need to:

  • remove the #include "test.c"
  • create a file test.h which contains the declaration: void test();
  • include the file test.h in main.c

Solution 7 - C

If you're using Visual Studio you could also do "#pragma once" at the top of the headerfile to achieve the same thing as the "#ifndef ..."-wrapping. Some other compilers probably support it as well .. .. However, don't do this :D Stick with the #ifndef-wrapping to achieve cross-compiler compatibility. I just wanted to let you know that you could also do #pragma once, since you'll probably meet this statement quite a bit when reading other peoples code.

Good luck with it

Solution 8 - C

Ages after this I found another problem that causes the same error and did not find the answer anywhere. I thought to put it here for reference to other people experiencing the same problem.

I defined a function in a header file and it kept throwing this error. (I know it is not the right way, but I thought I would quickly test it that way.)

The solution was to ONLY put a declaration in the header file and the definition in the cpp file.

The reason is that header files are not compiled, they only provide definitions.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJordiView Question on Stackoverflow
Solution 1 - CmouvicielView Answer on Stackoverflow
Solution 2 - CpaxdiabloView Answer on Stackoverflow
Solution 3 - CKasprzolView Answer on Stackoverflow
Solution 4 - CMuradView Answer on Stackoverflow
Solution 5 - CdirkgentlyView Answer on Stackoverflow
Solution 6 - CanonView Answer on Stackoverflow
Solution 7 - CcwapView Answer on Stackoverflow
Solution 8 - CLouisView Answer on Stackoverflow