Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multple c++ files causes "multiple definition" error?

I'm using multiple C++ files in one project for the first time. Both have need to include a protected (#ifndef) header file. However, when I do that, I get a multiple definition error.

What I have is two one .cpp file that calls the header directly, and one indirectly (Another include includes it) and then two other header files that include it.

So what do I need to do to get rid of the error?

ERROR:

obj\Debug\main.o||In function Z14sortLibQtyTest4BookS_':| [PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'

CODE:

bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }

It should be mentioned that this isn't the only function giving me problems, probably more than ten are, and some aren't so short and sweet. Also, the functions are needed in multiple files.

like image 564
David Avatar asked Oct 16 '25 18:10

David


2 Answers

You have two options to solve this multiple definition problem: Mark the method inline, or put the definition in a .cpp file.

1) Mark the method inline:

// Foo.h

inline bool foo(int i) { return i = 42; }

2) Put the definition in a .cpp file:

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition

Whether the method is actually inlined by the compiler in the first case is irrelevant here: inline allows you to define a non-member function in a header file without breaking the one definition rule.

like image 52
juanchopanza Avatar answered Oct 19 '25 07:10

juanchopanza


The ".cpp" and ".h" suffixes are largely a matter of convention. As far as the compiler is concerned, where a line of code came from is irrelevant. When you #include that function into your .cpp files, you are implementing that function in that .cpp file.

So when the compiler is done and it asks the linker to knit together the code from your two cpp files, it finds a conflict: two functions with the same name and fingerprint (arguments and return). This is an error.

You need to either:

a. Put the implementation in one source file, and just leave a prototype declaration in the header

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }

b. Mark the function as inline: when you call the function, the compiler will insert copies of the function body as needed which can be wasteful, but often times the compiler can figure out the efficient thing to do.

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }

c. Mark the function as "static" which tells the compiler to create a copy of the function for every source file that includes it, but not to expose it to the linker. If some source files include the header without using the function, the compiler has to detect this and remove it - which not all compilers/optimization levels do, so it can be doubly wasteful.

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }

d. Avoid the downsides of c, mark it static inline

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
like image 40
kfsone Avatar answered Oct 19 '25 07:10

kfsone