Duplicate Symbol Error C++

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 and lib.c both include lib.h, then they both have separate copies of lib.h compiled in.
  • If lib.h includes primes.h, then they both have their own separate copies of primes.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



Leave a reply



Submit