Duplicate Symbol in C
First off, including source files is a bad practice in C programming. Normally, the current translation unit should consist of one source file and a number of included header files.
What happens in your case is that you have two copies of the parse_file
function, one in each translation unit. When parser.c
is compiled to an object file, it has its own parse_file
function, and assembler.c
also has its own.
It is the linker that complains (not the compiler) when given two object files as an input, each of which contains its own definition of parse_file
.
You should restructure your project like this:
parser.h
void parse_file(char *);
parser.c
void parse_file(char *src_file) {
// Function here
}
assembler.c
/* note that the header file is included here */
#include "parser.h"
int main (void) {
parse_file("test.txt");
return 0;
}
Why is this not a duplicate symbol error?
Objective-C++ files (.mm) are C++ files, so they undergo name mangling. If you run nm
on the output, you'll see something along the lines of:
$ nm a.out | grep get_file
0000000100000fa0 T __Z8get_filePKc
0000000100000f70 T _get_file
If you applied extern "C"
in the C++ version to remove name mangling, you'd see the collision you're expecting:
// B.mm
extern "C" uint32_t get_file(const char *path)
{
return 0;
}
$ clang A.c B.mm
duplicate symbol _get_file in:
/var/folders/j3/32xftcp56c12hqz7y8rl4f600000gn/T/A-d00e10.o
/var/folders/j3/32xftcp56c12hqz7y8rl4f600000gn/T/B-d853af.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
C - Duplicate symbol if put include in header, but works fine if include in source file
When you include a file, the include is replaced with the file contents (and this continues until there are no more includes).
- If
main.c
andlib.c
both includelib.h
, then they both have separate copies oflib.h
compiled in. - If
lib.h
includesprimes.h
, then they both have their own separate copies ofprimes.h
compiled in. - If
primes.h
has an array defined, then they both have a copy of that array. - And if they both have anything with the same name defined in both files, you get a duplicate definition error.
The best way to fix this is to only have 1 definition of the primes
array with all of its values in a source file (e.g. lib.c
), and you need to use the extern
keyword in primes.h
with no values to declare that one of your files contains the actual array (you can leave the size unspecified in this case). Note that this use of the extern
keyword is a sort of promise to the compiler that there is some file containing the actual array, and that's why you still need the actual array in a source file:
// primes.h
extern uint64_t primes[];
// lib.c
#include "primes.h"
uint64_t primes[] = {
7,
11,
};
// main.c
#include "primes.h"
duplicate symbol error when compiling c++ code
Duplicate symbols means the linker faces the same function in both of your compilation units (main.cpp
and comp_fns.cpp
). Maybe you implemented the functions in the header without inline
?
Duplicate Symbols Error - Am I doing my includes right?
Both of the .cpp
files include, indirectly, BaseSpec.tpp
which defines:
void Base<int>::hello_base() const
That's your violation of the One Definition Rule, that results in a duplicate symbol link failure.
Removing BaseSpec.tpp
, and replacing it with a .cpp
file, with the same contents, should make the linkage error go away.
Duplicate symbol error when linking C code
Your header should never include a .c
file.
.c
files should include .h
files.
Each .c
file is its own "compilation unit". The compiler compiles all compilation units separately. You would include source.h
in source.c
, so that the header serves to provide the forward declarations of the functions implements in the compilation unit.
If you include source.c
in source.h
, then every compilation unit that includes source.h
(including source.c
) would get its own copy of the implementations defined in source.c
. That means there would be multiple definitions of the same things, and the compiler wouldn't know which one to pick. That's why you're getting this "duplicate" symbol error. I suspect both swift.c
and source.c
include source.h
.
Link Error: Duplicate Symbol
Since this is tagged C++17, you can take advantage of the new inline variables language feature:
namespace proj {
class A {};
inline A a;
} // namespace proj
inline
variables now behave the same way as inline
functions: your multiple definitions of a
get collapsed into one.
Related Topics
C++ Vector, What Happens Whenever It Expands/Reallocate on Stack
Initialise Eigen::Vector with Std::Vector
Should a Move Constructor Take a Const or Non-Const Rvalue Reference
How to Use an Array as Map Value
C++: When (And How) Are C++ Global Static Constructors Called
Why Does C++ Code Missing a Formal Argument Name in a Function Definition Compile Without Warnings
Template Function as a Template Argument
Why Is the Copy-Constructor Argument Const
Checking If an Iterator Is Valid
Why Destructor Is Not Called on Exception
What Is the Underlying Type of a C++ Enum
Cmake Externalproject_Add() and Findpackage()
What Is the Past-The-End Iterator in Stl C++
Choosing Embedded Scripting Language for C++
Boost::Flat_Map and Its Performance Compared to Map and Unordered_Map