Multiple Definition Error C++

How to prevent multiple definitions in 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

Multiple definition of ... linker error

Don't define variables in headers. Put declarations in header and definitions in one of the .c files.

In config.h

extern const char *names[];

In some .c file:

const char *names[] = { 
"brian", "stefan", "steve" };

If you put a definition of a global variable in a header file, then this definition will go to every .c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.

Also, one more thing you can do if you have to define your variables inside of a header file you can use the static keyword.

static const char *names[] = {
"brian", "stefan", "steve" };

This way variable names will be defined only once in your entire program and can be accessed multiple number of times.

Compiling error with errors like multiple definition

Inside your header file, you should declare your variable like:

extern const int khStrInt;

Then in a .c file, you should define it like:

const int khStrInt = 33;

This means the variable definition is only generated once by the compiler when compiling the .c file and so the linker doesn't see multiple definitions. Also, having the declaration in the header file allows other files which include the header to be able to use the variable.

Multiple definition, first defined here errors

The problem here is that you are including commands.c in commands.h before the function prototype. Therefore, the C pre-processor inserts the content of commands.c into commands.h before the function prototype. commands.c contains the function definition. As a result, the function definition ends up before than the function declaration causing the error.

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

#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.

However, including a .c file is a bad practice and should be avoided. A better solution for this problem would be to include commands.h in commands.c and link the compiled version of command to the main file. For example:

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

commands.c

#include "commands.h"

void f123(){} // function definition

Multiple definition error using header file

Your header file file2048.h contains variable declarations. When you include this file in other sorces files this causes the variable to be declader multiple times. Please look into the extern keyword.

Header File:

#ifndef FILE2048_H
#define FILE2048_H
#define SIZE 4

#ifdef __cplusplus
extern "C" {
#endif

/* - Bad implementation
int matrix[SIZE+1][SIZE+1]={0};
*/

//Better implementation
extern int matrix[SIZE+1][SIZE+1];
//Now define this variable only once, on "main.c" for example

.
.
.

#endif

c project makefile multiple definitions error

The last gcc run ...

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb   -DUSE_HAL_DRIVER -DSTM32F103xB -IInc  -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"master"  -mcpu=cortex-m3 -mthumb   -specs=nano.specs -TSTM32F103RBTx_FLASH.ld  -lc -lm -lnosys -Wl,-Map=build/myproject.map,--cref -Wl,--gc-sections  Src/master.c build/master.elf build/master.hex   -o master

... that generates the errors, is itself erroneous. Where does it come from?

Note the -o master at the end: there is no rule presented in the makefile whose recipe would produce such a compilation, but it is building a file with the same name, master, as the goal target. This is the result of the exercise of a built-in implicit rule for building an executable from a correspondingly-named C source file.

Several circumstances contribute to this.

  1. A request is made to build target master. It is the goal target in this case, but it would also suffice for it to be a prerequisite of another target that make wants to build.

  2. The makefile does not provide any recipe for building master.

  3. There is a source file named master.c. Although it is in subdirectory Src, there is a %vpath directive that tells make to treat files in that directory as if they appeared in the project root directory.

Additionally,


  1. The built-in rule is apparently including the declared prerequisites of target master (build/master.elf and build/master.hex) in the compilation command. This is not documented or standard for versions of make I've checked, and it is the reason for the multiple-definition errors: gcc is building an executable, so it provides standard _init and _fini functions, but the already-built executable build/master.elf that is included in the link also has these.

Since you don't actually want a file named master built, a good solution would be to declare that target phony:

.PHONY: master

That has several useful effects, but key for your purposes is that it causes the implicit rule search for that target to be skipped.



Related Topics



Leave a reply



Submit