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 thetest.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.
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 thatmake
wants to build.The makefile does not provide any recipe for building
master
.There is a source file named
master.c
. Although it is in subdirectorySrc
, there is a%vpath
directive that tellsmake
to treat files in that directory as if they appeared in the project root directory.
Additionally,
- The built-in rule is apparently including the declared prerequisites of target
master
(build/master.elf
andbuild/master.hex
) in the compilation command. This is not documented or standard for versions ofmake
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 executablebuild/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
How to Use Multiple Versions of Gcc
Best Library for Statistics in C++
Allocating Vectors (Or Vectors of Vectors) Dynamically
How to Compare Two Vectors for Equality Element by Element in C++
How to Get the String Representation of Hresult Value Using Win API
How to Write a Std::String to a Utf-8 Text File
How Do Memory_Order_Seq_Cst and Memory_Order_Acq_Rel Differ
When Virtual Inheritance Is a Good Design
Is There an Equivalent to Winapi's Max_Path Under Linux/Unix
How to Prevent an Object Being Created on the Heap
What Is the Size of an Enum Type Data in C++
Is There a Standard Way of Moving a Range into a Vector
Linux C++: How to Profile Time Wasted Due to Cache Misses
Sharing Precompiled Headers Between Projects in Visual Studio
What Is the Branch in the Destructor Reported by Gcov
Can You Have a Triple Minus Signs in C Programming? What Does It Mean